我不明白何时应该使用std::move,何时应该让编译器优化...例如:
using SerialBuffer = vector< unsigned char >;
// let compiler optimize it
SerialBuffer read( size_t size ) const
{
SerialBuffer buffer( size );
read( begin( buffer ), end( buffer ) );
// Return Value Optimization
return buffer;
}
// explicit move
SerialBuffer read( size_t size ) const
{
SerialBuffer buffer( size );
read( begin( buffer ), end( buffer ) );
return move( buffer );
}
Run Code Online (Sandbox Code Playgroud)
我应该使用哪个?
由于范围问题,我对此感到疑惑.例如,考虑代码
typedef struct {
int x1;/*top*/
int x2;/*bottom*/
int id;
} subline_t;
subline_t subline(int x1, int x2, int id) {
subline_t t = { x1, x2, id };
return t;
}
int main(){
subline_t line = subline(0,0,0); //is line garbage or isn't it? the reference
//to subline_t t goes out of scope, so the only way this wouldn't be garbage
//is if return copies
}
Run Code Online (Sandbox Code Playgroud)
所以我的问题是,返回语句是否总是复制?在这种情况下,它似乎工作,所以我被引导相信返回确实复制.如果它复制了,它会在每种情况下复制吗?
我距离最终掌握指针和参考的完整用途和概念(或者我希望如此)只有一步之遥,所以我需要你的帮助来清楚地解决问题.
我有一个包含一个对象的private成员向量ClassA,所以vector<myObj> vec.
我应该使用什么样的getter ClassA来返回vec所以我可以打印内容而myObj无需冗余分配内存?我需要通过returnvec reference,常规return vec,甚至指向vec
我有一个函数可以创建一个非常大的 std::vector。返回此向量时,由于其大小,我不想再次复制它。因此,我想返回对该向量的引用。但是,这样做会给我一个分段错误。为什么是这样?解决办法是什么?
这是我的代码:
std::vector<int>& Foo()
{
std::vector<int> x(100000, 50);
return x;
}
int main()
{
std::vector<int> y = Foo();
return 0;
}
Run Code Online (Sandbox Code Playgroud) 示例代码:
class Thingy
{
public:
void doStuff(std::string&);
std::string doStuff();
};
void Thingy::doStuff(std::string& str) {
str = "stuff";
}
std::string Thingy::doStuff() {
return "stuff";
}
int main(int argc, const char* args[])
{
std::string name;
Thingy thingy;
thingy.doStuff(name);
std::cout << name << " " << thingy.doStuff() << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
特别是对于字符串,要么是方法更有效,那么效率"值得"来扭曲代码的可读性或一致性?(例如,如果我不需要,我宁愿不创建名称变量)
事实上,这是(在一天结束时)与此讨论相关的字符串常量吗?
在以下代码中,字符串封装在类Foo中.
对Foo :: getText()的调用按值返回字符串.这将创建字符串对象的第二个实例,但现在两个字符串对象都指向堆上的相同char缓冲区.
删除Foo实例时,将自动销毁封装的字符串,因此将删除堆上的char缓冲区.
即使getText()按值返回字符串,生成的字符串对象仍依赖于原始字符串对象的生命周期,以便保留它们相互指向的char缓冲区.
这是不是意味着打印retval到终端是对堆已经免费的内存的无效访问?
class Foo
{
Foo(const char* text) :
str(text)
{
}
std::string getText()
{
return str;
}
std::string str;
};
int main()
{
Foo pFoo = new Foo("text");
std::string retval = foo.getText();
delete pFoo;
cout << retval; // invalid memory access to char buffer?
}
Run Code Online (Sandbox Code Playgroud)
我想很多人都认为,因为字符串是按值返回的,所以不需要关心Foo中原始字符串的生命周期.这个问题与字符串没有严格的关系,但实际上适用于任何具有封装指针的类,这些指针在销毁时是免费的.但是在弦乐方面,最好的做法是什么?
return std::string(retval.c_str());getText()?编辑:
我想我被RVO误导了.此示例中的所有三个字符串都在同一地址返回c_str.RVO应该受到指责吗?
class Obj
{
public:
Obj() : s("text")
{
std::printf("%p\n", s.c_str());
}
std::string getText() { …Run Code Online (Sandbox Code Playgroud)