gpt4 book ai didi

c++ - 存储作为参数传递的引用的内容

转载 作者:行者123 更新时间:2023-11-30 01:50:07 24 4
gpt4 key购买 nike

我正在用 C++/Qt 编程。这些代码片段是否通过复制正确保存了引用的内容?

带有初始化列表:

Foo(const Bar &bar) : bar(bar) { }
Bar bar; //member variable of Foo class

在 Setter 方法中:

void TestClass::setName(const QString &name) {
this->name = name;
}
QString name; //member variable of TestClass class

如果是,这会复制拷贝吗?:

void TestClass::setName(const QString name) {
this->name = name;
}
QString name; //member variable of TestClass class

这是否会导致未定义的行为,因为引用的对象可能会提前解构?

Foo(Bar &bar) : bar(bar) { }
Bar &bar; //member variable of Foo class

存储传递的引用的内容是不是不好的风格?传递需要存储的参数的更好方法是什么?

最佳答案

复制开销

这两种方法都会将输入字符串中的数据复制到类变量中:

QString name; //member variable of TestClass class

void TestClass::setName1(const QString & name) {
this->name = name;
}

void TestClass::setName2(const QString name) {
this->name = name;
}

在第二个中,QString 的拷贝将首先在堆栈上创建。您认为按值传递会导致更多的复制开销是正确的。这就是对于包含大量数据的类通常不鼓励按值传递的原因。

参见 this question有关按引用传递与按值传递的更多讨论。

但是,在这个具体的例子中,开销的差别非常小:QString 使用implicit sharing .当您复制 QString(例如使用 operator=)时,它只是创建对相同数据的另一个引用。因此,仅复制一个 QString —— 即使是一个很长的 QString —— 并不比复制一个引用更密集。

悬挂引用

Foo(Bar &bar) : bar(bar) { }
Bar &bar; //member variable of Foo class

如果原始 bar 被删除而您的 Foo 类仍然存在(这被称为“dangling reference”),那么这段代码确实会导致问题. 以这种方式使用引用很像使用指针:作为程序员,您需要确保所有涉及的对象都正确管理内存。

如果您担心 Qt 应用程序中的悬挂指针/引用,请尝试 QPointer :

A guarded pointer, QPointer, behaves like a normal C++ pointer T *, except that it is automatically set to 0 when the referenced object is destroyed (unlike normal C++ pointers, which become "dangling pointers" in such cases). T must be a subclass of QObject.

你可以像这样重写上面的代码:

Foo(Bar * bar) : bar(bar) { }
QPointer<Bar> bar; //member variable of Foo class

然后你就部分地避免了悬挂指针错误:

Bar * myBar = new Bar();
Foo myFoo(myBar); // myFoo->bar is set to myBar
delete myBar; // myFoo->bar becomes 0

只要您的类方法在使用它之前检查this->bar 是否为空,您就可以避免对未初始化的内存进行操作。 (或者,如果不这样做,您会很快遇到段错误,而不是访问已删除的地址时可能出现更微妙的未定义行为。)

关于c++ - 存储作为参数传递的引用的内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27976092/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com