委托构造函数和引用参数
Delegating constructors and reference parameters
我想通过重载为我的 class 实现几个构造函数。据我了解,遵循 DRY 原则,惯用地执行此操作的方法是使用称为委托构造函数的功能。我也看到了关于在任何地方使用引用参数并不惜一切代价避免使用指针的想法,因为引用是一种 C++ 方式等等。
所以这是我认为可以用指针实现的方式(有效):
class B {};
class C {};
class A {
public:
A();
A(const B* b);
A(const B* b, const C* c);
private:
const B* b_;
const C* c_;
};
// These ctors short and concise, delegating work to last ctor
A::A() : A(nullptr, nullptr) {}
A::A(const B* b) : A(b, nullptr) {}
// This ctor contains code that deals with b or c being nullptr
// Ideally I only modify code in this ctor (DRY)
A::A(const B* b, const C* c) : b_(b), c_(c) {
//code
}
以下 显然 不起作用:
class B {};
class C {};
class A {
public:
A();
A(const B& b);
A(const B& b, const C& c);
private:
const B& b_;
const C& c_;
};
A::A() : A(nullptr, nullptr) {}
A::A(const B& b) : A(b, nullptr) {}
A::A(const B& b, const C& c) : b_(b), c_(c) {
//code
}
所以问题是如何按照指针示例中的语义实现委托构造函数,但将引用作为构造函数的参数。
(我是否完全忽略了这里的重点?甚至可能盯着整体想法看?)
您不能将 nullptr
传递给引用。它的存在正是为了这个目的。
指针是包含变量地址的变量。引用是地址变量,所以它不能引用任何东西,也不能被重新分配。
当你写
A(const B& b)
您正在签订合同。你说的是:"I want to construct A with a mandatory B object. B being null is not an option here."
委托给这个构造函数意味着遵循它的契约。因此,根据这个假设,您的代表团可以正常工作:
struct B{};
struct A{
A() : A(B{}){} // Constructing a pre-defined B object
A(const B& b) : _b{b}{}
B _b;
};
int main ()
{
A a;
}
说,如果你想表达一个可为 null 的类型,你可以使用 std::optional
如果 C++17 是一个选项。如果您有多态对象,我建议您使用智能指针来更好地表达所有权并更好地控制您的代码。
假设您的 'A' 成员是引用,允许这样做的一种方法是为每个 类:
设置一些特殊的 "null" 值
class B {};
class C {};
class A
{
public:
A();
A(const B& b);
A(const B& b, const C& c);
private:
const B& b_;
const C& c_;
static const B null_b;
static const C null_c;
};
A::A() : A(null_b, null_c) {}
A::A(const B& b) : A(b, null_c) {}
A::A(const B& b, const C& c) : b_(b), c_(c) {
}
我想通过重载为我的 class 实现几个构造函数。据我了解,遵循 DRY 原则,惯用地执行此操作的方法是使用称为委托构造函数的功能。我也看到了关于在任何地方使用引用参数并不惜一切代价避免使用指针的想法,因为引用是一种 C++ 方式等等。
所以这是我认为可以用指针实现的方式(有效):
class B {};
class C {};
class A {
public:
A();
A(const B* b);
A(const B* b, const C* c);
private:
const B* b_;
const C* c_;
};
// These ctors short and concise, delegating work to last ctor
A::A() : A(nullptr, nullptr) {}
A::A(const B* b) : A(b, nullptr) {}
// This ctor contains code that deals with b or c being nullptr
// Ideally I only modify code in this ctor (DRY)
A::A(const B* b, const C* c) : b_(b), c_(c) {
//code
}
以下 显然 不起作用:
class B {};
class C {};
class A {
public:
A();
A(const B& b);
A(const B& b, const C& c);
private:
const B& b_;
const C& c_;
};
A::A() : A(nullptr, nullptr) {}
A::A(const B& b) : A(b, nullptr) {}
A::A(const B& b, const C& c) : b_(b), c_(c) {
//code
}
所以问题是如何按照指针示例中的语义实现委托构造函数,但将引用作为构造函数的参数。
(我是否完全忽略了这里的重点?甚至可能盯着整体想法看?)
您不能将 nullptr
传递给引用。它的存在正是为了这个目的。
指针是包含变量地址的变量。引用是地址变量,所以它不能引用任何东西,也不能被重新分配。
当你写
A(const B& b)
您正在签订合同。你说的是:"I want to construct A with a mandatory B object. B being null is not an option here."
委托给这个构造函数意味着遵循它的契约。因此,根据这个假设,您的代表团可以正常工作:
struct B{};
struct A{
A() : A(B{}){} // Constructing a pre-defined B object
A(const B& b) : _b{b}{}
B _b;
};
int main ()
{
A a;
}
说,如果你想表达一个可为 null 的类型,你可以使用 std::optional
如果 C++17 是一个选项。如果您有多态对象,我建议您使用智能指针来更好地表达所有权并更好地控制您的代码。
假设您的 'A' 成员是引用,允许这样做的一种方法是为每个 类:
设置一些特殊的 "null" 值class B {};
class C {};
class A
{
public:
A();
A(const B& b);
A(const B& b, const C& c);
private:
const B& b_;
const C& c_;
static const B null_b;
static const C null_c;
};
A::A() : A(null_b, null_c) {}
A::A(const B& b) : A(b, null_c) {}
A::A(const B& b, const C& c) : b_(b), c_(c) {
}