【发布时间】:2016-06-01 08:10:06
【问题描述】:
我是 C++ 的新手,我正在尝试了解构建类的良好做法。
假设我有一堂课Foo:
class Foo {
public:
double foo;
Foo(double foo);
Foo add(Foo f);
}
我想创建一个类 Bar,它由两个 Foo 对象组成,并在构造时创建第三个。
第一种选择:对象作为类成员
class Bar {
public:
Foo foo1;
Foo foo2;
Foo foo3;
Bar(const Foo &f1, const Foo &f2);
}
Bar::Bar(const Foo &f1, const Foo &f2):
{
foo1 = f1;
foo2 = f2;
foo3 = f1.add(f2);
}
因为我没有为
Foo定义默认构造函数,所以它不起作用。
第二个选项:指针作为类成员
class Bar {
public:
const Foo* foo1;
const Foo* foo2;
const Foo* foo3;
Bar(const Foo &f1, const Foo &f2);
}
Bar::Bar(const Foo &f1, const Foo &f2):
{
foo1 = &f1;
foo2 = &f2;
foo3 = &(f1.add(f2));
}
注意:我必须将
foo1和foo2声明为const才能使构造函数工作。 但它仍然失败,因为对于foo3,我正在获取临时结果的地址,这是非法的。
哪个选项更自然(以及如何修复错误)?我觉得第一个选项可能更好,但是我的 Foo 对象必须在内存中创建两次,不是吗? (一次调用构造函数,第二次由构造函数自己调用)
任何帮助表示赞赏。
【问题讨论】:
-
首先我没有定义默认构造函数:在这种情况下使用member initializer list。第二:使用指针做引用的事情,
std::unique_ptr用于所有权。第三:避免不必要的动态分配,尝试使用值类型编码并仅在真正需要时分配(即用于容器)。 -
问问自己,指针所指向的对象是否曾经被破坏,以及何时、由谁破坏。如果答案很明确,那么对象的生命周期就在可控范围内,那么一切正常。
-
如果您在第一个示例中没有
Foo的默认构造函数,您仍然可以使用成员初始化器列表正确初始化它。 -
你的第二个选项简直太糟糕了。您正在获取作为 const 参考传递给您的某物的地址。这可能是暂时的!
-
@bullsy:这个问题显然是重复的,但那里的答案早于 C++11 ......而且这个问题的任何答案至少没有提到
std::unique_ptr是错误的。不确定在这种情况下正确的 SO 协议是什么。