我正在使用 C++/Qt 进行编程。这些代码片段是否通过复制正确保存了引用的内容?
带有初始化列表:
Foo(const Bar &bar) : bar(bar) { }
Bar bar; //member variable of Foo class
Run Code Online (Sandbox Code Playgroud)
在 Setter 方法中:
void TestClass::setName(const QString &name) {
this->name = name;
}
QString name; //member variable of TestClass class
Run Code Online (Sandbox Code Playgroud)
如果是,这会复制副本吗?:
void TestClass::setName(const QString name) {
this->name = name;
}
QString name; //member variable of TestClass class
Run Code Online (Sandbox Code Playgroud)
这是否会导致未定义的行为,因为引用的对象可能会提前解构?:
Foo(Bar &bar) : bar(bar) { }
Bar &bar; //member variable of Foo class
Run Code Online (Sandbox Code Playgroud)
存储传递引用的内容是不是不好的风格?传递需要存储的参数的更好方法是什么?
这两种方法都会将数据从输入字符串复制到类变量中:
\nQString name; //member variable of TestClass class\n\nvoid TestClass::setName1(const QString & name) {\n this->name = name;\n}\n\nvoid TestClass::setName2(const QString name) {\n this->name = name;\n}\nRun Code Online (Sandbox Code Playgroud)\n在第二个中,将首先在堆栈上创建 QString 的副本。您认为按值传递会导致更多复制开销的想法是正确的。这就是对于包含大量数据的类通常不鼓励使用值传递的原因。
\n有关按引用传递与按值传递的更多讨论,请参阅此问题。
\n然而,在这个具体的例子中,开销的差异非常小:QString 使用隐式共享。当您复制QString(例如使用operator=)时,它只是创建对相同数据的另一个引用。因此,仅复制 QString \xe2\x80\x94,即使是很长的 \xe2\x80\x94 并不比复制引用更密集。
\nFoo(Bar &bar) : bar(bar) { }\nBar &bar; //member variable of Foo class\nRun Code Online (Sandbox Code Playgroud)\nbar如果在您的类仍然存在的情况下删除原始代码Foo(这称为“悬空引用”),则该代码确实会导致问题。以这种方式使用引用很像使用指针:作为程序员,您需要确保所有涉及的对象正确管理内存。
如果您担心 Qt 应用程序中的悬空指针/引用,请尝试QPointer:
\n\n\n受保护的指针 QPointer 的行为类似于普通的 C++ 指针 T *,不同之处在于当引用的对象被销毁时,它会自动设置为 0(与普通的 C++ 指针不同,在这种情况下,普通 C++ 指针会变成“悬空指针”)。T 必须是 QObject 的子类。
\n
您可以像这样重写上面的代码:
\nFoo(Bar * bar) : bar(bar) { }\nQPointer<Bar> bar; //member variable of Foo class\nRun Code Online (Sandbox Code Playgroud)\n那么你就可以部分避免悬空指针错误:
\nBar * myBar = new Bar();\nFoo myFoo(myBar); // myFoo->bar is set to myBar\ndelete myBar; // myFoo->bar becomes 0\nRun Code Online (Sandbox Code Playgroud)\n只要您的类方法this->bar在使用之前检查 null ,就可以避免对未初始化的内存进行操作。(或者,如果不这样做,您很快就会遇到分段错误,而不是访问已删除的地址而导致潜在的更微妙的未定义行为。)
| 归档时间: |
|
| 查看次数: |
3079 次 |
| 最近记录: |