如何绕过使用相同参数从派生 class 调用基 class 构造函数?
How to get around calling base class constructor from derived class with the same arguments?
我想使用定义“接口”的基础对象,然后让派生对象实现它。每个对象都使用其名称进行初始化,这始终是相同的过程:使用传递给构造函数的参数写入成员“name_”。在这方面,我希望派生对象的行为方式与基础对象完全相同,因此每个派生对象都应该写入其名称 varialbe。但是,问题是我需要在 every 派生对象中定义一个额外的构造函数来写入 name 变量,这很麻烦。由于这个原因,以下示例无法编译。有什么办法解决这个问题,或者继承甚至是正确的方法(请随时提出其他建议)?
非编译代码(显示我想做的):
#include <iostream>
class A {
const std::string name_;
public:
A(const std::string name) : name_(name) { std::cout << "creation of object " << name_ << "; this name = " << this->name_ << '\n'; }
};
class B : public A {
// const std::string name_; -- we do not even need this because "name_" also exists for object B.
// C++ misses its constructor here :') - I don't
};
int main()
{
A obj_a{ "A" };
B obj_b{ "B" };
}
相关错误:
source>:20:18: error: no matching function for call to 'B::B(<brace-enclosed initializer list>)'
20 | B obj_b{ "B" };
| ^
<source>:12:7: note: candidate: 'B::B(const B&)'
12 | class B : public A {
| ^
<source>:12:7: note: no known conversion for argument 1 from 'const char [2]' to 'const B&'
<source>:12:7: note: candidate: 'B::B(B&&)'
<source>:12:7: note: no known conversion for argument 1 from 'const char [2]' to 'B&&'
ASM generation compiler returned: 1
<source>: In function 'int main()':
<source>:20:18: error: no matching function for call to 'B::B(<brace-enclosed initializer list>)'
20 | B obj_b{ "B" };
| ^
<source>:12:7: note: candidate: 'B::B(const B&)'
12 | class B : public A {
| ^
<source>:12:7: note: no known conversion for argument 1 from 'const char [2]' to 'const B&'
<source>:12:7: note: candidate: 'B::B(B&&)'
<source>:12:7: note: no known conversion for argument 1 from 'const char [2]' to 'B&&'
您可以使用 using-declaration 到
Using-declaration
[...] introduce base class members into derived class definitions.
[...]
If the using-declaration refers to a constructor of a direct base of the class being defined (e.g. using Base::Base;
), all constructors of that base (ignoring member access) are made visible to overload resolution when initializing the derived class.
If overload resolution selects an inherited constructor, it is accessible if it would be accessible when used to construct an object of the corresponding base class: the accessibility of the using-declaration that introduced it is ignored.
这样:
class B : public A {
using A::A;
};
请注意 using-declaration 本身的可访问性被忽略的突出显示,这意味着示例中的 using A::A
不需要放在 public
可访问性下 - 重要的是可访问性B
.
中的继承构造函数
甚至显式添加 B 构造函数
class B : public A
{
public:
B(const std::string& s) : A(s) {}
};
或“使用”基地的
class B : public A
{
public:
using A::A;
};
我想使用定义“接口”的基础对象,然后让派生对象实现它。每个对象都使用其名称进行初始化,这始终是相同的过程:使用传递给构造函数的参数写入成员“name_”。在这方面,我希望派生对象的行为方式与基础对象完全相同,因此每个派生对象都应该写入其名称 varialbe。但是,问题是我需要在 every 派生对象中定义一个额外的构造函数来写入 name 变量,这很麻烦。由于这个原因,以下示例无法编译。有什么办法解决这个问题,或者继承甚至是正确的方法(请随时提出其他建议)?
非编译代码(显示我想做的):
#include <iostream>
class A {
const std::string name_;
public:
A(const std::string name) : name_(name) { std::cout << "creation of object " << name_ << "; this name = " << this->name_ << '\n'; }
};
class B : public A {
// const std::string name_; -- we do not even need this because "name_" also exists for object B.
// C++ misses its constructor here :') - I don't
};
int main()
{
A obj_a{ "A" };
B obj_b{ "B" };
}
相关错误:
source>:20:18: error: no matching function for call to 'B::B(<brace-enclosed initializer list>)'
20 | B obj_b{ "B" };
| ^
<source>:12:7: note: candidate: 'B::B(const B&)'
12 | class B : public A {
| ^
<source>:12:7: note: no known conversion for argument 1 from 'const char [2]' to 'const B&'
<source>:12:7: note: candidate: 'B::B(B&&)'
<source>:12:7: note: no known conversion for argument 1 from 'const char [2]' to 'B&&'
ASM generation compiler returned: 1
<source>: In function 'int main()':
<source>:20:18: error: no matching function for call to 'B::B(<brace-enclosed initializer list>)'
20 | B obj_b{ "B" };
| ^
<source>:12:7: note: candidate: 'B::B(const B&)'
12 | class B : public A {
| ^
<source>:12:7: note: no known conversion for argument 1 from 'const char [2]' to 'const B&'
<source>:12:7: note: candidate: 'B::B(B&&)'
<source>:12:7: note: no known conversion for argument 1 from 'const char [2]' to 'B&&'
您可以使用 using-declaration 到
Using-declaration
[...] introduce base class members into derived class definitions.
[...]
If the using-declaration refers to a constructor of a direct base of the class being defined (e.g. using
Base::Base;
), all constructors of that base (ignoring member access) are made visible to overload resolution when initializing the derived class.If overload resolution selects an inherited constructor, it is accessible if it would be accessible when used to construct an object of the corresponding base class: the accessibility of the using-declaration that introduced it is ignored.
这样:
class B : public A {
using A::A;
};
请注意 using-declaration 本身的可访问性被忽略的突出显示,这意味着示例中的 using A::A
不需要放在 public
可访问性下 - 重要的是可访问性B
.
甚至显式添加 B 构造函数
class B : public A
{
public:
B(const std::string& s) : A(s) {}
};
或“使用”基地的
class B : public A
{
public:
using A::A;
};