关于c ++:如果类被分成单独的文件,则不调用默认构造函数

Default constructor not called if classes devided into separate files

更新:

现在我有了这个,它没有编译:
啊:

1
2
3
4
5
6
7
8
9
10
11
12
13
#ifndef A_H
#define A_H

class A {
private:
    int foo;

public:
    A();
    int getfoo();
};

#endif

A.cpp:

1
2
3
4
5
6
7
8
9
#include"A.h"

A::A() {
    foo = 5;
}

int A::getfoo(){
    return foo;
}

B.h:

1
2
3
4
5
6
7
8
9
10
11
12
13
#ifndef B_H
#define B_H

class B {
private:
    A myA;

public:
    B();
    int getAvalue();
};

#endif

B.cpp:

1
2
3
4
5
6
#include"A.h"
#include"B.h"

int B::getAvalue(){
    return myA.getfoo();
}

错误:

1
2
3
b.h line 6: C2146: missing ';' before identifier 'myA'
b.h line 6: C4430: missing type specifier - int assumed
b.h line 6: C4430: missing type specifier - int assumed

结束更新

我在不同的cpp和头文件中编写了2个类:A类和B类。
B类使用A类作为私有变量,从不调用A类的默认构造函数。
这是我的代码:

啊:

1
2
3
4
5
class A {
public:
    A();
    int getfoo();
};

A.cpp:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class A {
private:
    int foo;
public:
    A();
    int getfoo();
};

A::A() {
    foo = 5;
}

int A::getfoo(){
    return foo;
}

B.h:

1
2
3
4
class B {
public:
    int getAvalue();
};

B.cpp:

1
2
3
4
5
6
7
8
9
10
11
12
#include"A.h"

class B {
private:
    A myA;
public:
    int getAvalue();
};

int B::getAvalue(){
    return myA.getfoo();
}

classtest.cpp:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include"stdafx.h"
#include <iostream>
#include"B.h"

using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
    B stackB;
    cout << stackB.getAvalue() << endl;

    B* storeB = new B();
    cout << storeB->getAvalue() << endl;

    cin.get();
    return 0;
}

输出永远不会是5,并且永远不会触发构造函数A :: A()内的断点。如果我在全球或本地使用B并不重要。如果我将类和函数放在一个文件中,那么这个示例完全正常。

如果我向类B添加一个空的默认构造函数,则会调用类A的默认构造函数,但随后Visual Studio 2008会抱怨变量stackB周围的堆栈损坏。

我究竟做错了什么?


只有这个班级:

A.h:

1
2
3
4
5
class A {
public:
    A();
    int getfoo();
};

A.cpp:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class A {
private:
    int foo;
public:
    A();
    int getfoo();
};

A::A() {
    foo = 5;
}

int A::getfoo() {
    return foo;
}

您在A.h中声明class A

然后在您的实现(cpp)文件中,您再次声明class A
您还忘记在A.cpp中包含A.h。如果你把标题包含在cpp中;编译器会抛出错误告诉你出了什么问题。您还缺少标题保护或pragma指令。

你的课应该是这样的:

1
2
3
4
5
6
7
8
9
10
11
12
#ifndef A_H
#define A_H

class A {
private:
    int foo;
public:
    A();
    int getFoo() const;  // const to return member and prevents modification
};

#endif // !A_H

A.cpp

1
2
3
4
5
6
7
8
9
#include"A.h" // you forgot to include the header

A::A() : // class constructor using it's member initializer list
    foo( 5 ) {
}

int A::getFoo() const {
    return foo;
}

现在,一旦修好了课程,那么研究B课应该不是问题。但是,将一个类的头文件包含到另一个类时,有一点需要注意;你可以最终得到循环包含。防止这种情况的最好方法是在标头中使用类原型,并在包含类的cpp文件中包含其标头。在某些情况下,一个类原型不起作用,但我会留给你做研究。

如何在C ++中使用Class Prototype

B类可能如下所示:

B.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#ifndef B_H
#define B_H

// #include"A.h"  // uncomment this if prototype below doesn't work.
class A; // class prototype may not work in all cases;
// If the above prototype does not work; comment it out
// and replace it with #include"A.h".


class B {
private:
    A myA;

public:
    B(); // remove default
    int getAValue() const;
};

#endif // !B_H

B.cpp

1
2
3
4
5
6
7
8
9
10
#include"B.h"
#include"A.h" // If class A's prototype in the header does not work
// then comment this out and place it in this class B's header by
// replacing it with the prototype.

B::B() {} // default constructor (should make this complete type)

int B::getAValue() const {
    return myA.getFoo();
}

这应该有助于解决您的问题。如果使用类原型在标题中不起作用,因为在某些情况下它可能不会;您可以从标头中删除原型声明,并将其替换为该类的include指令,并从cpp文件中删除其include。