返回常量对象引用 (getter) 和仅返回字符串有什么区别?
What's the difference between returning a const object reference (getter), and just the string?
我正在浏览c++网站教程,这是对我这学期(初学者(正在学习的大学课程的一种很好的赞扬。在学习复制构造函数和析构函数时,我遇到了以下代码段:
// destructors
#include <iostream>
#include <string>
using namespace std;
class Example4 {
string* ptr;
public:
// constructors:
Example4() : ptr(new string) {}
Example4 (const string& str) : ptr(new string(str)) {}
// destructor:
~Example4 () {delete ptr;}
// access content:
const string& content() const {return *ptr;}
};
int main () {
Example4 foo;
Example4 bar ("Example");
cout << "bar's content: " << bar.content() << 'n';
return 0;
}
现在,我理解了析构函数部分,但字符串成员的getter让我感到困惑。为什么要返回对对象(本例中为字符串(的引用(别名(?
// access content:
const string& content() const {return *ptr;}
这和只返回字符串有什么区别?
string content() const {
return *ptr;
}
返回常量别名是否更有效?您返回的只是字符串的地址,还是字符串本身?如果只是返回字符串,你会返回整个字符串吗?谢谢
返回字符串是不可取的,原因有两个:
- 这意味着执行了不必要的字符串副本,这对性能不利
- 这也意味着,有人可能会试图修改返回的字符串,认为他们修改了类的实际成员——
const
引用不允许这样做,并触发编译错误
const string& content() const {return *ptr;}
[返回引用]与,只是把绳子还回来?
string content() const { return *ptr;}
您可能会问这两者之间是否有区别并且只返回指针
const string* content() const { return ptr;}
- 我没有发现一个比另一个有优势
好吧,也许考虑一下字符串包含2600万个字符的场景,你可能想避免复制它。
但是,如果只是为了评估你在这里学到的东西,你还应该意识到另一个问题(或者可能是2个(。
在Lubuntu 18.04上,使用g++(Ubuntu 7.3.0-27(,一个字符串s,没有数据,
std::string s;
cout << sizeof(s) << " " << s.size() << endl;
报告数字"32 0"。
std::string s ("01234567890123456789");
cout << sizeof(s) << " " << s.size() << endl;
报告值"32 20">
{
std::string s;
for (int i=0; i<1000000; i++)
{
for (char j='A'; j<='Z'; j++)
s.push_back(j);
}
cout << " " << sizeof(s) << " " << s.size() << endl;
}
报告值"32 26000000">
100万个字母
s仍然只有32字节
由此,您可以得出a("string"的实例占用32个字节,而与数据无关。b( 因为所有数据都位于其他地方c(,所以std::string实例中的32个字节中的一些字节是指向动态内存中字符所在位置的指针。
嗯。
如果obj实例只有32个字节,那么您可能会问Example4为什么使用指针将这个SMALL对象(字符串实例(放入动态内存中。。。使用8个字节找到32,然后需要第二个引用(字符串实例内部的某个指针(来到达Example4字符串的char。
同样,std::向量是24个字节(不管元素有多少,也不管元素有多大(。std::vector负责内存管理,这样你就不必这么做了。
也许这节课是为了帮助你发现和评估动态记忆中的内容,以及自动记忆中的信息,以改进你的选择。
关键思想是STL库容器为您处理动态内存,从而大大简化您的工作。
或者,也许教授想让你更多地了解你正在使用的工具。在某些方面,标准容器将您与这些东西的工作方式隔离开来。也许这项任务是为了了解std::string的作用。
//这里有一些"g++-std=c++17"代码,可以一步到位,说明的几个想法
#include <iostream>
using std::cout, std::endl;
#include <sstream>
using std::stringstream;
#include <iomanip>
using std::setfill, std::setw;
#include <string>
using std::string;
#include <cstring>
using std::strlen;
class Example4
{
string* ptr;
public:
Example4() : ptr(new string) {}
Example4 (const string& str) : ptr(new string(str)) {}
~Example4 () {delete ptr;}
// access content:
const string& content() const {return *ptr;}
const string* contentP() const {return ptr;}
string show(string lbl)
{
stringstream ss;
ss << "n " << lbl
<< " . 5 4 3 2 1"
<< "n . '09876543210987654321098765432109876543210987654321'"
<< "n " << "*ptr : '" << *ptr << "'"
<< "n " << "(*ptr).size() : " << (*ptr).size()
<< "n " << " ptr->size() : " << ptr->size()
<< "n " << "strlen((*ptr).c_str()) : " << strlen((*ptr).c_str())
<< "n " << "strlen(ptr->c_str()) : " << strlen(ptr->c_str())
<< "nn " << "sizeof(*ptr) : " << sizeof(*ptr)
<< " @ 0x" << ptr << ',' // where ptr points to
<< "n " << "sizeof (ptr) : " << sizeof(ptr)
<< "nn";
return ss.str();
}
};
class T996_t
{
public:
int operator()() { return exec(); }
private: // methods
int exec()
{
Example4 e4("Now is the time to answer all questions01234567890");
cout << "n " << e4.show("Example4")
<< "n '" << e4.content() << "'"
<< "n '" << *e4.contentP() << "'nn"
<< endl;
{
std::string s;
cout << " " << sizeof(s) << " " << s.size() << endl;
}
{
std::string s("01234567890123456789");
cout << " " << sizeof(s) << " " << s.size() << endl;
}
{
std::string s;
for (int i=0; i<1000000; i++)
{
for (char j='A'; j<='Z'; j++)
s.push_back(j);
}
cout << " " << sizeof(s) << " " << s.size() << endl;
}
return 0;
}
}; // class T996_t
int main(int, char**) { return T996_t()(); }
这段代码在我的Lubuntu上编译并运行。我的make文件构建的编译命令以开头
g++ -std=c++17 -m64 -ggdb
- 返回常量对象引用 (getter) 和仅返回字符串有什么区别?
- C 字符串返回字符串的整数/双精度/长整型值
- 如何从COM模块中的函数返回字符串数组?
- React Native (Android):无法通过 JNI 在 jobject 中返回字符串
- 我如何在函数 cpp 中返回字符串
- 我有一个返回字符串向量的函数.它需要两个字符串,并且返回一个字符串中缺少的字符串
- 格式化返回字符串C++
- 返回字符串vs通过引用传递字符串以更新值
- 如何在不使用 STL 的情况下从函数反转字符串后返回字符串C++?
- 使用 ctypes 从函数返回字符串C++会给出大的 int,而不是 char 指针
- 从 C++ 中的模板函数返回字符串和整数
- 返回字符串的散点回文计数
- C++重载字符串 [] 运算符以返回字符串和
- 返回字符串和不同向量数据类型的映射C++
- 字符串函数不返回字符串? C++
- 从函数返回字符串C++错误
- 如何在返回字符串的函数中不忽略void值
- 我想将字符串转换为 Json 格式并返回字符串向量作为答案
- C - 返回字符串时的分割故障
- 使用向量和字符串函数返回字符串