对派生类使用不同的基构造函数 C++

发布于 2024-11-29 23:50:46 字数 392 浏览 0 评论 0原文

根据我的理解,以下代码将按此顺序执行:

  1. 调用派生构造函数。
  2. 基础对象是使用默认的基础构造函数构造的。
  3. 执行派生构造函数的主体。

如果是的话,成员z不是被赋值两次了吗?

class base {
public:
    int x, y, z;
    base() {x = 0; y = 0; z = 0;};
};

class derived : public base {
public:
    derived() {z = 5;};
};

是否有一种更有效的方法来创建“派生”类的对象,以便它使用不同的构造函数,在本例中,该构造函数仅分配成员 x 和 ya 值,而让 z 在继承()中分配一个值?

From my understanding the following code will execute in this order:

  1. Derived constructor is called.
  2. Base object is constructed using the default base constructor.
  3. Body of the derived constructor executes.

If so, isn't the member z is assigned a value twice?

class base {
public:
    int x, y, z;
    base() {x = 0; y = 0; z = 0;};
};

class derived : public base {
public:
    derived() {z = 5;};
};

Is there a more efficient way to create an object of class "derived" so it uses a different constructor, in this case, one that would only assign members x and y a value, leaving z to be assigned a value in derived()?

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

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

发布评论

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

评论(5

清风夜微凉 2024-12-06 23:50:46

是的,有一种更有效的方法,但它会花费更多的代码(从而增加维护开销)。

class base {
public:
    int x, y, z;
    // Default constructor
    base() {x = 0; y = 0; z = 0;};
    // Constructor to be called if you want to override the z value
    base(int zValue) { x=0; y=0; z=zValue; };
};

class derived : public base {
public:
    derived() : base(5) {};
};

Yes, there is a more efficient way, but it will take more code (thus increasing the maintenance overhead).

class base {
public:
    int x, y, z;
    // Default constructor
    base() {x = 0; y = 0; z = 0;};
    // Constructor to be called if you want to override the z value
    base(int zValue) { x=0; y=0; z=zValue; };
};

class derived : public base {
public:
    derived() : base(5) {};
};
堇色安年 2024-12-06 23:50:46

是的,在您的示例中,z 被分配了两次,就像它看起来的那样。

为了做你想做的事,你可以做这样的事情,这需要几乎完全相同数量的代码(只是在这里和那里移动一些代码):

class base {
public:
    int x, y, z;
    base(int z = 0) : x(), y(), z(z) { }
};

class derived : public base {
public:
    derived() : base(5) { } // with this one, z is assigned 5 once
    // or
    derived() { } // z is assigned 0 once
};

Yes, z is assigned twice in your example, just what it looks like.

To do what you're wanting, you could do something like this, which requires almost exactly the same amount of code (just moving some here and there):

class base {
public:
    int x, y, z;
    base(int z = 0) : x(), y(), z(z) { }
};

class derived : public base {
public:
    derived() : base(5) { } // with this one, z is assigned 5 once
    // or
    derived() { } // z is assigned 0 once
};
浅笑轻吟梦一曲 2024-12-06 23:50:46

当然。使用所谓的 ctor-initializer

class base {
public:
    int x, y, z;
    base(int z = 0) : x(0), y(0), z(z) {};
};

class derived : public base {
public:
    derived() : base(5) {}
};

构造函数声明中 : 之后和第一个 { 之前的代码是 ctor-初始化器。 (有些人称其为“初始化器列表”,但 C++ 标准称之为“构造函数初始化器”。)

只要有可能,您就应该始终使用构造器初始化器将类成员初始化为某个值。虽然这对于 int 来说并不重要,但使用ctor-initializer 进行初始化可能比默认构造类成员然后赋值更快。

Sure. Use what's called a ctor-initializer:

class base {
public:
    int x, y, z;
    base(int z = 0) : x(0), y(0), z(z) {};
};

class derived : public base {
public:
    derived() : base(5) {}
};

The code after the : and before the first { in the constructor declaration is a ctor-initializer. (Some people call it an "initializer list", but ctor-initializer is what the C++ standard calls it.)

You should always use ctor-initializers whenever you can to initialize class members to some value. While it doesn't really matter for ints, initialization using ctor-initializers can be faster than default constructing class members then assignment.

冷…雨湿花 2024-12-06 23:50:46

当然,你可以做到。

使用成员初始化列表作为:

class base {
public:
    int x, y, z;
    base(int a, int b, int c) : x(a), y(b), z(c) {}
                           //^^^^^^^^^^^^^^^^^^^ it's member-initialization-list!

};

class derived : public base {
public:
    derived() : base(0,0,5) {}
            // ^^^^^^^^^^^ call the specific base constructor
};

Definitely, you can do that.

Use member-initialization-list as:

class base {
public:
    int x, y, z;
    base(int a, int b, int c) : x(a), y(b), z(c) {}
                           //^^^^^^^^^^^^^^^^^^^ it's member-initialization-list!

};

class derived : public base {
public:
    derived() : base(0,0,5) {}
            // ^^^^^^^^^^^ call the specific base constructor
};
幸福不弃 2024-12-06 23:50:46

为了详细说明安德鲁的答案,如果您想真正确保base所有成员仅设置一次,并且以尽可能最有效的方式,您可以使用成员列表初始值设定项而不是在构造函数中设置值。

class base {
public:
    int x, y, z;
    base() : x(0), y(0), z(0) {};
    base( int xval, int yval, int zval ) : 
            x(xval), y(yval), z(zval) 
            { };
};

class derived : public base {
public:
    derived() : base( 0, 0, 5 ) {};
};

大多数编译器都会为 : x(_x), ... 生成与在构造函数中设置值相同的代码,但我见过一些编译器没有这样做。

To elaborate on Andrew's answer, if you wanted to really make sure that all of base's members were set only once, and in the most efficient way possible, you could use a member-list initializer rather than setting values in the constructor.

class base {
public:
    int x, y, z;
    base() : x(0), y(0), z(0) {};
    base( int xval, int yval, int zval ) : 
            x(xval), y(yval), z(zval) 
            { };
};

class derived : public base {
public:
    derived() : base( 0, 0, 5 ) {};
};

Most compilers will generate the same code for : x(_x), ... as just setting the values in the constructor, but I've seen a couple that did not.

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