很基本的问题。与设计偏好有关,但我认为我需要注意一些注意事项。
我想在另一个类中有某个类的实例。我看到的方式有3种选择:
将对象class2
放入class1
其中,如下所示。这意味着在构造的实例时class1
会构造它。我的问题是可能需要默认和/或复制构造函数?当我在class1
下面实例化一个对象时,它是否class2_inst(args)
使用该构造函数进行构造?还是class2_inst
已经使用某些默认构造函数创建了该行,而该行class2_inst(args)
仅复制了一个匿名class2
对象?
class class2 {
public class2(args) {
...
}
}
class class1 {
protected class2 class2_inst;
public class1(args) : class2_inst(args) {
...
}
}
我可以指向class2
:
class class2 {
public class2(args) {
...
}
}
class class1 {
protected class2* class2_inst;
public class1(args) {
class2_inst = new class2(args);
...
}
}
这样做的好处是,在我显式调用new运算符之前,不会实例化class2。
然后使用引用而不是指针:
class class2 {
public class2(args) {
...
}
}
class class1 {
protected class2& class2_inst;
public class1(args) {
class2_inst = new class2(args);
...
}
}
我想让class2_inst
自己的生活与之相称class1
。在class2_inst
外面住不有趣class1
。因此,引用可能是要走的路。
在这三种方法中,哪个是每个人的首选方法,为什么?
您的示例有些落后。我认为您的意思是:
class class2 {
public:
class2(args) {
...
}
};
class class1 {
protected:
class2 class2_inst;
public:
class1(args) : class2_inst(args) {
...
}
};
class class2 {
public:
class2(args) {
...
}
};
class class1 {
protected:
class2* class2_inst;
public:
class1(args) {
class2_inst = new class2(args);
...
}
};
class class2 {
public:
class2(args) {
...
}
};
class class1 {
protected:
class2& class2_inst;
public:
class1(args) {
class2_inst = new class2(args);
...
}
};
现在,这样说:
例1将很好地工作,你想要的东西,而且是要走的首选方式:“我想要class2_inst
的生活,时间匹配的class1
无滑稽的业务有。class2_inst
生活之外class1
,并回答你的问题-是的,”class2_inst(args)
会class2_inst
直接构造成员,而不是默认构造成员,然后将匿名class2
对象复制到该成员中。请参阅构造函数和成员初始化器列表。
例2也将工作,但要使其工作正常,你需要一个析构函数添加class1
到delete
了new'edclass2
对象,你还需要添加复制/移动构造函数和复制/移动赋值操作符来class1
复制/移动class2
对象正确,按照3/5/0的规则。
class class2 {
public:
class2(args) {
...
}
};
class class1 {
protected:
class2* class2_inst;
public:
class1(args) {
class2_inst = new class2(args);
...
}
class1(const class1 &src) {
class2_inst = new class2(*(src.class2_inst));
...
}
class1(class1 &&src) {
class2_inst = src.class2_inst;
src.class2_inst = nullptr;
...
}
~class1(args) {
delete class2_inst;
}
class1& operator=(const class1 &rhs) {
if (this != &rhs) {
class1 tmp(rhs);
std::swap(class2_inst, tmp.class2_inst);
}
return *this;
}
class1& operator=(class1 &&rhs) {
class1 tmp(std::move(rhs));
std::swap(class2_inst, tmp.class2_inst);
return *this;
}
};
在示例1中,您可以免费获得所有这些功能,因为编译器将自动为您生成这些额外的方法。是的,在某些情况下,为成员使用指针更有意义,但此示例不是其中之一。
示例3完全无效。您不能将对象指针分配给对象引用。为何您会认为“引用可能是路要走”?在这种情况下,它们不是。
因此,简而言之,您应该尽可能使用值语义,但在需要时使用指针/引用语义。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句