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;
}
您在
然后在您的实现(cpp)文件中,您再次声明
您还忘记在
你的课应该是这样的:
啊
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。