C++:包含父类时出现多定义错误
C++: Multiple definition error when including parent class?
我正在用派生类编写一个简单的银行程序,在包含父类时遇到Multiple definition of <method name>
错误。
请记住,我昨天刚开始用C++编写代码,从Java/PHP过渡到处理头/定义对我来说有点困惑。请纠正您发现的任何错误!
以下是我的文件/代码示例:
文件
- 帐户.h
- Account.cpp(超级)
- 支票帐户.cpp(子项)
- SavingsAccount.cpp(儿童)
当将父类(Account.cpp)包含到任何文件中时,都可以重现错误。我已经将代码减少了很多,但它应该让您了解我是如何处理继承的。
需要说明的是,当我#include
时,任何文件的子类(ChequingAccount.cpp)都可以正常工作,继承的函数也可以正常工作。但是,当我#include
时,父类(Account.cpp)会中断编译器,所有方法都会出现Multiple definition of <method name>
错误。
同样,我不确定这是否是正确的方法,但这是我从教程中了解到的。
代码
账户.h
#ifndef ACCOUNT_H
#define ACCOUNT_H
class Account
{
protected:
double m_balance;
public:
Account(double balance); // Constructor.
virtual ~Account(); // Destructor.
// Accessor Methods.
double getBalance() const;
// Mutator Methods.
virtual void withdrawFunds(double amount);
void depositFunds(double amount);
};
#endif
Account.cpp(超类)
#include "Account.h"
Account::Account(double balance = 0)
{
m_balance = balance;
}
Account::~Account()
{
// TODO: Delete this data structure...
}
double Account::getBalance() const
{
return m_balance;
}
void Account::withdrawFunds(double amount)
{
m_balance -= amount;
}
void Account::depositFunds(double amount)
{
m_balance += amount;
}
支票账户.cpp(儿童)
#include "Account.h"
class ChequingAccount: public Account
{
public:
ChequingAccount(int id, int userId, double balance) : Account(id, balance){};
void withdrawFunds(double amount)
{
// Override parent method.
}
};
如有任何帮助,我们将不胜感激!非常感谢。
当您#包含"some file.cpp"时,您正在指示编译器将该cpp文件的内容复制到程序中的该点。这将创建"some file"的两个编译版本,这将导致"Multiple Definitions"。
首先,在基类和子类中声明的"相同"函数不会导致多重定义错误。
这里只有一个例子和解释,旨在帮助你理解我的观点:
main.cpp
class father{
void fun();
}
void father::fun(){}
class son : public father{
void fun();
}
void son::fun(){}
int main()
{
return 0;
}
你编译它,肯定没有多重定义错误。在Java中,我们在类中定义函数。在C++中,只有内联函数在类中定义,其他函数是声明,可以在任何时候声明。参见定义语法:father::fun
son::fun
。它们实际上定义了两个不同的函数,一个在father
中,另一个在son
中。因此不存在多重定义错误。再一次,在类声明中,您只能定义内联函数,也只能声明非内联函数。因此,存在多个定义错误。这只是为了帮助你以语法的方式理解它。
顺便说一句,如果编译器未能内联,也不会出现多重定义错误,因为即使您在头文件中定义内联函数并将文件包含在任何位置,内联函数也是内部链接的。
我编译了你的代码,并在你定义的构造函数中得到了不同的错误。无论如何,使用"include"
包含cpp文件意味着您不了解实现文件和接口文件的要点。
您还需要在child的.cpp文件中显式地将child的方法声明为子类的成员。见下文:
支票账户.cpp(儿童)
#include "Account.h"
class ChequingAccount: public Account
{
public:
ChequingAccount(int id, int userId, double balance) : Account(id, balance){};
void ChequingAccount::withdrawFunds(double amount)
{
// Override parent method.
}
};
在定义void ChequingAccount::withdrawFunds(double)
时,您已经定义了void Account::withdrawFunds(double)
。
尝试virtual void ChequingAccount::withdrawFunds(double)
virtual关键字类似于Java中的override。
简而言之,不应该包含cpp文件。
出现多重定义错误的原因实际上与类继承无关。
考虑一个简单的例子:
add.h:
#ifndef __ADD_H_
#define __ADD_H_
int add(int a);
#endif
add.cpp:
#include "add.h"
int add(int a) { return a + 1; }
main.cpp:
#include "add.h"
int main() { return add(-1); }
C++处理#include
指令的方法只是复制粘贴包含的文件并替换#include
行。因此,如果我们手动扩展上述文件,我们将得到以下内容:
add.cpp:
#ifndef __ADD_H_
#define __ADD_H_
int add(int a);
#endif
int add(int a) { return a + 1; }
main.cpp:
#ifndef __ADD_H_
#define __ADD_H_
int add(int a);
#endif
int main() { return add(-1); }
这会很好用的。(我们可以对一个函数进行多次声明)
但是,如果您决定包含.cpp文件而不是.h文件,如以下代码所示:
main.cpp:
#include "add.cpp" // notice here
int main() { return add(-1); }
如果你像我们刚才那样扩展它:
add.cpp:
#ifndef __ADD_H_
#define __ADD_H_
int add(int a);
#endif
int add(int a) { return a + 1; }
main.cpp:
#ifndef __ADD_H_
#define __ADD_H_
int add(int a);
#endif
int add(int a) { return a + 1; }
int main() { return add(-1); }
您将看到该代码包含函数add
的多个定义,其中一个在add.cpp
中,另一个在main.cpp
中。当将这两个文件链接在一起时(每个.cpp文件都是使用编译器单独编译的,然后使用链接器链接在一起),链接器会被add
的两个定义弄糊涂,不知道该使用哪一个,所以它会开始抱怨。
- 使用命名空间时出现多个定义错误
- 对C宏的未定义引用,但在定义它时会出现重新定义错误
- 尝试调用 .h 文件中定义的变量时出现变量未定义错误
- 在头文件和 cpp 文件中使用一次 #pragma 时出现结构重定义错误
- 链接阶段出现多重定义错误
- 避免模板类中的重定义错误
- 即使我没有包含多个文件,C++中的多个定义错误
- 跨多个类的全局变量而不会出现重定义错误?
- 尝试运行 wasm 函数时出现模块未定义错误
- C++ 预期的左大括号以及重定义错误
- C++:成员的越界声明必须是纯虚函数的定义错误
- c++中数组的未定义错误
- Visual C:模板类中的自定义错误消息
- 为什么C++模板不会导致多个定义错误?
- 只有一个定义/声明时标头声明变量的多堆定义错误
- C++ 在多个其他类中使用单个类 - 编译时出现多个定义错误
- 基类未定义.错误 C2504
- Q 斯坦达项重定义错误
- 可视化C++中的结构定义错误
- VC++ C2011 重定义错误 - 未使用的头文件