我正在创建一个C ++类,它有一个对象成员变量B,默认情况下不应该实例化。我不喜欢使用指针语法,因为B类在operator()中依赖很多,而且代码变得非常混乱。
为了使用引用作为成员变量,但每次我想通过引用访问对象时,我最终都会出现分段错误。
是否有可能使这项工作?
class SomeClass {
public:
SomeClass(int argToInitSomeOtherClass);
void someOtherFunction();
private:
std::shared_ptr < SomeOtherClass > MemberObject;
SomeOtherClass & MemberObjectReference = * MemberObject;
};
class SomeOtherClass {
public:
SomeOtherClass(int initArg) {
this - > member = initArg;
};
void whatever() {}; // I do nothing
private:
int member;
};
SomeClass::SomeClass(int argToInitSomeOtherClass) {
MemberObject = std::make_shared < SomeOtherClass > (argToInitSomeOtherClass)
}
void SomeClass::someOtherFunction() {
MemberObjectReference.whatever(); // Segmentation fault
}
如果有一种方法来保存成员对象并以非静态方式实例化它而没有默认值也解决了我的问题,但我认为这是不可能的。
我不确定OP究竟打算实现什么目标。
我会寻找另一种设计,因为OP的方法在我看来很脆弱,并且容易在源代码变化最小的情况下中断。
但是,OP的实际错误是IMHO构造函数中的初始化错误:
必须在初始化共享指针后进行引用。另外,一旦共享指针被重新分配,我就会使共享指针const
重击,这将破坏(引用将变为悬空)。 (const
使这种尝试成为编译器错误。)
引用一个指针(无论是指针还是智能指针)应该仔细考虑指针的生命周期。 C ++中的引用本身并不这样做 - 这是作者的责任。
OP的固定示例:
#include <memory>
#include <iostream>
struct SomeOtherClass {
int member;
explicit SomeOtherClass(int initArg = 0): member(initArg) { }
void whatever() { std::cout << "SomeOtherClass::member: " << member << '\n'; }
};
class SomeClass {
public:
explicit SomeClass(int argForOther);
SomeClass(const SomeClass&) = delete;
SomeClass& operator=(const SomeClass&) = delete;
void someOtherFunction();
private:
const std::shared_ptr<SomeOtherClass> MemberObject;
SomeOtherClass &MemberObjectReference;
};
SomeClass::SomeClass(int argForOther):
MemberObject(std::make_shared<SomeOtherClass>(argForOther)),
MemberObjectReference(*MemberObject)
{ }
void SomeClass::someOtherFunction()
{
MemberObjectReference.whatever(); // Segmentation fault fixed
}
int main()
{
SomeClass someClass(123);
someClass.someOtherFunction();
return 0;
}
输出:
SomeOtherClass::member: 123