C++:继承字段的初始化

发布于 2024-09-28 09:27:10 字数 656 浏览 3 评论 0原文

我有一个关于派生类构造函数中继承成员初始化的问题。示例代码:

class A
    {
public:
    int m_int;
    };

class B: public A
    {
public:
    B():m_int(0){}
    };

此代码给出以下输出:

在构造函数 'B::B()' 中: 第 10 行:错误:类“B”没有任何名为“m_int”的字段

(请参阅 http://codepad .org/tn1weFFP

我猜为什么会发生这种情况? m_int 应该是 B 的成员,并且父类 Am_int 初始化时应该已经初始化>B 发生(因为父构造函数在继承类的成员初始化之前运行)。我的推理哪里有错误?这段代码到底发生了什么?

编辑:我知道初始化此成员的其他可能性(基本构造函数或派生构造函数中的赋值),但我想了解为什么我尝试的方式是非法的?一些特定的 C++ 语言功能或类似的功能?如果可能的话,请给我指出 C++ 标准中的一段话。

I've a question about initialization of inherited members in constructor of derived class. Example code:

class A
    {
public:
    int m_int;
    };

class B: public A
    {
public:
    B():m_int(0){}
    };

This code gives me the following output:

In constructor 'B::B()':
Line 10: error: class 'B' does not have any field named 'm_int'

(see http://codepad.org/tn1weFFP)

I'm guessing why this happens? m_int should be member of B, and parent class A should already be initialized when initialization of m_int in B happens (because parent constructors run before member initialization of inherited class). Where is a mistake in my reasoning? What is really happens in this code?

EDIT: I'm aware of other possibilities to initialize this member (base constructor or assignment in derived constructor), but I want to understand why is it illegal in the way I try it? Some specific C++ language feature or such? Please point me to a paragraph in C++ standard if possible.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

知足的幸福 2024-10-05 09:27:10

您需要为 A 创建一个构造函数(它可以受到保护,因此只有 B 可以调用它),它会像您一样初始化 m_int ,然后在您有 的地方调用 :A(0) : m_int(0)

您也可以在 B 的构造函数主体中设置 m_int = 0 。它是可访问的(正如您所描述的),只是在特殊的构造函数语法中不可用。

You need to make a constructor for A (it can be protected so only B can call it) which initializes m_int just as you have, then you invoke :A(0) where you have :m_int(0)

You could also just set m_int = 0 in the body of B's constructor. It is accessible (as you describe) it's just not available in the special constructor syntax.

白龙吟 2024-10-05 09:27:10

为了构造 B 类的实例,您首先要实例化 A 类的实例。在实例化期间,m_int 被初始化。初始化之后,b 的构造函数被调用,因此您无法重新初始化 m_int。如果这是您的目标,那么您可以为 A 实现一个采用 int 的构造函数,然后在 B 的初始化列表中调用它:

class A
{
public:
  A(int x): m_int(x) {}
  int m_int;
};

class B: public A
{
public:
  B(): A(2) {}
};

In order to construct an instance of class B you first instantiate an instance of class A. During that instantiation m_int gets initialized. It's after that intialization that b's constructor is called, so you can't reinitialize m_int. If that's your goal then you can implement a constructor for A that takes an int and then call that in B's initialization list:

class A
{
public:
  A(int x): m_int(x) {}
  int m_int;
};

class B: public A
{
public:
  B(): A(2) {}
};
我爱人 2024-10-05 09:27:10

您想要的是这样的:

class A{
public:
    A() : m_int(0);
    int m_int;
};

以便在正确的位置初始化 m_int

编辑:

从上面的评论来看,当您尝试初始化 B 中的 m_int 变量时,编译器抱怨的原因是它已经被 A 的构造函数初始化了。也就是说,你不能重新初始化某些东西,只能重新分配。因此,您可以像上面提到的 Ben Jackson 那样重新分配,或者您可以在适当的位置进行初始化。

What you want is this:

class A{
public:
    A() : m_int(0);
    int m_int;
};

so that m_int is initialized in the correct place.

Edit:

From a comment above, the reason the compiler complains when you try to initialize the m_int variable in B is that it's already been initialized by the constructor of A. That is, you can't re-initialize something, only reassign. So, you can reassign like Ben Jackson stated above or you can initialize in the proper place.

尝蛊 2024-10-05 09:27:10

在A中创建一个构造函数
并使用 B(): A(2) {}
代替 B():m_int(0){}
它的工作。

make a constructor in A
and use B(): A(2) {}
insteed of B():m_int(0){}
its working.

玩世 2024-10-05 09:27:10

遵循本·杰克逊的第一个建议。第二个(即在构造函数主体中设置 m_int = 0)只要 m_int 不是 const 就可以。我相信如果 m_int 是 const (但第一个建议会),这将不起作用,除非您打算使其可变,否则我会建议这样做。

所以,做:

class A {
protected:
    A():m_int{0}{} // Move constructor to parent class
    
public:
    const int m_int;
    auto print() {std::cout << m_int << std::endl;} // For example
};

class B: virtual public A {
public:
    B():A(){}
};

示例:

auto x {B()};
x.print() // Prints 0

Go with the first suggestion by Ben Jackson. The second one (i.e. set m_int = 0 in the body of the constructor) is OK as long as m_int is not a const. I believe this would not work if m_int were const (but the first suggestion would), which, unless you intend to make mutable, I would recommend.

So, do:

class A {
protected:
    A():m_int{0}{} // Move constructor to parent class
    
public:
    const int m_int;
    auto print() {std::cout << m_int << std::endl;} // For example
};

class B: virtual public A {
public:
    B():A(){}
};

Example:

auto x {B()};
x.print() // Prints 0
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文