繁体   English   中英

为什么? 未初始化的父类成员的隐式初始化

[英]Why? Implicit initialization from uninitialized parent class members

我在C ++初始化方面有令人讨厌的经验,我试图查看是否存在一个真实的示例,该示例无法证明编译器没有警告。

下面的代码可以正确编译,但是foo和bar被初始化为未初始化值(我假设未初始化的父类是)。 g ++和VS的编译器均不发出任何警告。 有人告诉我,让成员公开而不装饰他们是不好的行为。 但是,我认为编译器可能会发现这种不一致,并且至少会在最高警告级别发出警告,因为我看不到任何此类代码的应用程序。

#include <iostream>
using namespace std;

class base_class {
    public:
        int foo;
        int bar;

    base_class(int foo,int bar):
        foo(foo),bar(bar) 
    {}
};

class derived_class: public base_class {
    public:
    derived_class(int Foo, int Bar):
        base_class(foo,bar)
    { 
                    int a = Foo * Bar;

                    a++;
                    cout << foo << " " << bar << endl;
    }
};

int main ()
{
    derived_class *buzz = new derived_class(1,2);
    buzz->print();
}

我认为您的问题是您的构造函数参数使用大写字母:

通过以下代码,我得到了正确的值:

#include <iostream>
using namespace std;

class base_class {
    public:
        int foo;
        int bar;

    base_class(int foo,int bar):
        foo(foo),bar(bar)
        {
        int a = foo * bar;

        a++;

        cout << "Base : " << foo << ", " << bar << ", " << a << endl;
    }

};

class derived_class: public base_class {
    public:
    derived_class(int foo, int bar):
        base_class(foo,bar)
    {
        cout << "derived : " << foo << ", " << bar << endl;
    }
};

int main ()
{
    derived_class baz(1,2);
}

输出:

Base : 1, 2, 3
derived : 1, 2

然后发生的是,您的成员已使用未初始化的成员值“初始化”了:)

MY2C

您更新的代码揭示了您的问题:

在第17行中,您使用base_class foo和bar来调用base_class的构造函数, base_class使用当时尚未初始化的值。 结果是不确定的行为,从而产生奇怪的值。 正如Mike所说:仅在启用优化的情况下才会收到警告,这很奇怪。

这个:

#include <iostream>

class base_class {
public:
    int foo;
    int bar;
    base_class(int foo,int bar) : foo(foo),bar(bar) {}
};

class derived_class : public base_class {
public:
    derived_class(int foo, int bar) : base_class(foo,bar) {}
};

int main ()
{
    derived_class baz(1,2);
    std::cout << baz.foo << ", " << baz.bar << '\n';
    return 0;
}

使用VC9和VC10对我来说可以正常编译,并且在两种情况下都写1, 2 你还有别的吗?

但是请注意,将成员变量和构造函数参数命名为相同名称必然会造成混淆。

标准免责声明:除此类愚蠢的示例外,切勿使用public数据。

警告在编译时使用未初始化的变量的分析非常复杂,似乎GCC仅在启用优化时才这样做。 大概有人认为这会减慢无法优化的构建速度。

使用g++ -Wall -O编译代码会发出警告。 我无法在Visual Studio上发表评论。

我认为您并没有在所有警告都激活的情况下进行编译(并且您确实应该这样做)。 例如,在您的代码上,这是g ++的输出:

g++ -O3 -W -Wall    init.cc   -o init
init.cc: In function ‘int main()’:
init.cc:22: warning: ‘baz.derived_class::<anonymous>.base_class::foo’ is used uninitialized in this function
init.cc:28: note: ‘baz.derived_class::<anonymous>.base_class::foo’ was declared here
init.cc:22: warning: ‘baz.derived_class::<anonymous>.base_class::bar’ is used uninitialized in this function
init.cc:28: note: ‘baz.derived_class::<anonymous>.base_class::bar’ was declared here

您会注意到-W -Wall以确保最大程度的警告。 否则,如前所述,该错误用于变量初始化。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM