在另一个类中访问类的智能指针的属性时出现分段错误
我试图做到这一点:
#include <iostream>
#include <memory>
class B
{
public:
std::string var;
B()
{
var = "original";
}
void print()
{
std::cout << "composition " << std::endl;
}
};
class A
{
public:
int a_attribute = 10;
std::unique_ptr<B> b;
};
int main()
{
A a;
a.b->print();
}
这似乎工作正常,除非我尝试访问 B 的属性,例如:
std::string test = a.b->var;
这会导致 segmentation failure
错误,
为什么我没有收到 ab->print();
但出现段错误 ab->var;
?
i tried to make this:
#include <iostream>
#include <memory>
class B
{
public:
std::string var;
B()
{
var = "original";
}
void print()
{
std::cout << "composition " << std::endl;
}
};
class A
{
public:
int a_attribute = 10;
std::unique_ptr<B> b;
};
int main()
{
A a;
a.b->print();
}
That seems to work fine, except when i try to access the attributes of B, with e.g:
std::string test = a.b->var;
which leads to segmentation fault
error
why i'm not getting an error to a.b->print();
but getting segfault to a.b->var;
?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
你的问题就在这里,在 A 中你
创建了一个指向 B 对象的智能指针。 但是如果它没有指向 B 对象。在使用它之前,您必须创建一个 B 对象并将“b”设置为指向它。
我不确切知道如何以及何时创建 B,但您可以这样做,
这将使用默认构造函数创建一个新的 B 并使“ab”指向它。这是更有效的速记法
,显式创建 B,然后设置 ab 指向它。
请注意,您不必释放 B 对象。这就是智能指针的意义所在,他们会为你做这件事。
您问为什么有些组合有效而有些组合无效。
你有未定义的行为。这可以做任何事情,包括最糟糕的事情,看起来可行。然后在圣诞节前夕的午夜,您最大的客户向您的系统提交了一份巨额订单,然后系统崩溃了。每个专业开发人员都曾遇到过这种情况。避免方法:提高编译器警告级别,永远不要忽略警告。使用 valgrind 等工具或其他商业检查工具。
对我来说,您发布的原始代码有效。为什么,因为调用的方法实际上不需要 B 对象中的任何数据。但是如果我更改为这一点,
它会失败,因为现在我们正在引用 B 对象中的数据,但没有数据。
请注意,在不同的编译器上,您的原始代码将无法工作
You problem is here, in A you have
this creates a smart pointer to a B object. But it there is no B object that it points at. Before you can use it you must create a B object and set 'b' to point at it.
I dont know exactly how and when you want to create your B but you can do this
this will create a new B using the default contructor and make 'a.b' point at it. This is more effiecient short hand for
which explicitly creates a B and then sets a.b to point at it.
Note that you do not have to free the B object. Thats the point of smart pointers they will do it for you.
You asked why some combinations work and some dont.
You had Undefined Behavior. This can do anyting , including worst of all, appearing to work. Then at midnight on Christmas eve your largest customer submits a huge order to your system and it crashes. Every professional dev has had some occurrence of this. Ways to avoid: crank up the compiler warning levels, never ignore warnings. Use a tool like valgrind or other commercial checker tools.
For me your original code as posted worked. Why, because the invoked method doesnt actually need any data in the B object. But If I change to this
it fails because now we are referencing data in the B object, but there isn't one.
Note that on a different compiler your original code will not work