为什么 C++构造函数继承?

发布于 2024-11-24 08:16:59 字数 290 浏览 0 评论 0原文

为什么这段代码中需要 Child 传递构造函数?我认为不会,但是当我删除它时编译器(gcc 和 VS2010)会抱怨。有一个优雅的解决方法吗?必须将此填充程序插入到子类中似乎毫无意义。

class Parent
{
public:
  Parent(int i) { }
};

class Child : public Parent
{
public:
  Child(int i) : Parent(i) { }
};

int main()
{
  Child child(4);
  return 0;
}

Why is the Child pass-through constructor necessary in this code? I would think that it wouldn't be, but the compiler (gcc and VS2010) complains when I remove it. Is there an elegant workaround? It just seems pointless to have to insert this shim into child classes.

class Parent
{
public:
  Parent(int i) { }
};

class Child : public Parent
{
public:
  Child(int i) : Parent(i) { }
};

int main()
{
  Child child(4);
  return 0;
}

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

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

发布评论

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

评论(7

烟火散人牵绊 2024-12-01 08:17:00

因为以下内容完全有效:

class Parent
{
public:
    Parent(int i) { }
};

class Child : public Parent
{
public:
    Child() : Parent(42) { }
};

编译器如何猜测您是否希望派生子级具有转发的构造函数?在多重继承的情况下,两种类型的构造函数集可能不匹配;当从基类 A 转发构造函数时,应该调用基类 B 上的哪个构造函数?

从技术上讲,我想语言设计者可能会说,如果类型具有单个基类并且在没有显式构造函数的情况下,则转发所有父构造函数。但是,这会产生相反的问题:如果基类具有多个构造函数(包括默认构造函数),并且子类希望仅允许使用默认构造函数,则现在必须显式指定它。

Because the following is perfectly valid:

class Parent
{
public:
    Parent(int i) { }
};

class Child : public Parent
{
public:
    Child() : Parent(42) { }
};

How is the compiler to guess whether you want the derived child to have a forwarded constructor? And in the case of multiple inheritance, the set of constructors from the two types may not match; when forwarding a constructor from base class A, which constructor on base class B should be called?

Technically, I suppose the language designers could have said that if the type has a single base class and in the absence of an explicit constructor, all parent constructors are forwarded. However, that creates the opposite problem: if a base class has multiple constructors including a default constructor, and the child wishes to allow only the default constructor, this must now be explicitly specified.

活泼老夫 2024-12-01 08:17:00

如果您没有显式指定应调用哪个父构造函数,编译器将生成调用默认(无参数或使用所有默认值)构造函数的代码。

在您的情况下,类 Parent 没有这样的构造函数,编译器将不知道 i 使用什么值。

在类 Child 中未指定构造函数意味着将调用类 Parent 中的默认构造函数,但该构造函数不存在。


我还没有尝试过,但看看 这一部分C++0x 常见问题解答。我的印象是你所要求的在 C++0x 中是可能的。

If you don't specify which parent constructor should be called explicitly, the compiler will generate code which calls the default (no-argument or with all default values) constructor.

In your case, the class Parent does not have such a constructor, the compiler would not know what value to use for i.

Not specifying a constructor in class Child means that the default constructor in class Parent would be called but this does not exist.


I haven't tried it but have a look at this section of the C++0x FAQ. I have the impression what you're asking for is possible in C++0x.

断桥再见 2024-12-01 08:17:00

这是因为在 C++ 中你有多重继承。在下面的例子中,哪个构造函数应该被继承?

class Parent1
{
public:
  Parent1(int i) { }
};

class Parent2
{
public:
  Parent2(int i) { }
};

class Child : public Parent1, public Parent2
{
};

It's because in C++ you have multiple inheritance. In the following example, which constructor should be inherited?

class Parent1
{
public:
  Parent1(int i) { }
};

class Parent2
{
public:
  Parent2(int i) { }
};

class Child : public Parent1, public Parent2
{
};
走过海棠暮 2024-12-01 08:17:00

有优雅的解决方法吗?

从 C++11 开始,您可以使用 using 声明 来继承来自基类的构造函数(不包括默认、复制或移动构造函数):

class Parent
{
public:
  Parent(int i) { }
};

class Child : public Parent
{
public:
  using Parent::Parent; // inherits Parent(int)
};

int main()
{
  Child child(4);
  return 0;
}

Is there an elegant workaround?

Since C++11, you can use a using declaration to inherit constructors (not including default, copy or move constructors) from a base:

class Parent
{
public:
  Parent(int i) { }
};

class Child : public Parent
{
public:
  using Parent::Parent; // inherits Parent(int)
};

int main()
{
  Child child(4);
  return 0;
}
她比我温柔 2024-12-01 08:17:00

这是另一种情况

class Parent
{
public:
  Parent(int i) {this.i = i; }
  Parent() {this.i = 0;}
private:
  int i;
};

class Child : public Parent
{
public:
  Child(int i) : { }
};

int main()
{
  Child child(4);
  return 0;
}

,鉴于此,应该调用哪个 Parent 构造函数。如果 Parent 定义了一个接受 long 的构造函数,而不是接受 int 的构造函数,该怎么办?编译器是否应该自动将 int 转换为 long

无论好坏,语言设计者选择了简单性——从派生类自动调用的唯一构造函数是默认(无参数或所有参数都有默认值)构造函数。其他一切都需要显式调用。

Here's another case

class Parent
{
public:
  Parent(int i) {this.i = i; }
  Parent() {this.i = 0;}
private:
  int i;
};

class Child : public Parent
{
public:
  Child(int i) : { }
};

int main()
{
  Child child(4);
  return 0;
}

Given that, which Parent constructor should be called. What if Parent defines a constructor that takes in a long but not one that takes an int? Should the compiler auto-convert the int to long?

For better or worse, the language designers opted for simplicity -- the only constructor that is automatically called from a derived class is the default (no-arg or all args having defaults) constructor. Everything else needs to be explicitly called.

蓝颜夕 2024-12-01 08:17:00

编译器仅自动生成默认构造函数,即不带参数的 ctr,但前提是您尚未定义任何构造函数。

在这种情况下,您有(在父级中),因此不会为您设置默认值,而且子级需要它,以便它知道如何处理您传递给它的参数i

The compiler only autogenerates the default constructor, that is the ctr without parameters, but only if you haven't defined any constructors.

In this case, you have (in the parent), so no default is made for you, plus the child needs it so that it knows what to do with the parameter i that you are passing to it.

可可 2024-12-01 08:17:00

如果您不想使用编译器生成的默认构造函数,则需要由子构造函数显式调用构造函数,该默认构造函数称为默认构造函数(不带参数的构造函数)。但显然在您的情况下,您需要一个接受 int 的构造函数,然后您必须显式调用它。

Constructors need to be called explicitly by the child constructor if you don't want to use the default one which generated by compiler, which is called default constructor (the one with no arguments). But apparently in your case you want a constructor that accepts an int, then you have to call it explicitly.

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