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

时间:2010-06-21 08:39:57

标签: c++ oop compiler-warnings

我对C ++初始化有一个讨厌的经历,我试图看看是否有一个真实的例子证明编译器没有警告。

以下代码编译正确,但foo和bar使用uninit值初始化(我假设来自未初始化的父类)。编译器,包括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();
}

5 个答案:

答案 0 :(得分:1)

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

使用以下代码,我得到了正确的值:

#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

答案 1 :(得分:1)

您的更新代码会显示您的问题:

在第17行中,您使用base_class中的foo和bar来调用base_class的构造函数,其值为尚未初始化的值。结果是未定义的行为,因此是奇怪的值。正如迈克所说:只有在优化开启时才会收到警告,这很奇怪。

答案 2 :(得分:0)

此:

#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数据。

答案 3 :(得分:0)

需要警告在编译时使用未初始化变量的分析非常复杂,并且GCC似乎只在启用优化时执行此操作。据推测,有人认为它放慢了非优化构建的速度令人无法接受。

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

答案 4 :(得分:0)

我认为你没有编译所有激活的警告(你真的应该)。例如,在您的代码中,这是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以确保最大警告。否则,如前所述,错误是在用于变量初始化的情况下。