C ++:包含父类时的多个定义错误?

时间:2014-09-10 00:58:41

标签: c++ inheritance include multiple-definition-error

我正在编写一个包含派生类的简单银行程序,并且在包含父类时遇到Multiple definition of <method name>错误。

请记住,我刚开始使用C ++进行编码,并且从Java / PHP转移,处理标题/定义对我来说有点混乱。请纠正你看错了!

以下是我的文件/代码示例:

文件

  • Account.h
  • Account.cpp(超级)
  • ChequingAccount.cpp(儿童)
  • SavingsAccount.cpp(儿童)

将父类(Account.cpp)包含到任何文件中时,错误可以重现。我已经减少了很多代码,但它应该让你知道我如何处理继承。

澄清一下,当我#include任何文件的子类( ChequingAccount.cpp )工作正常,并且继承的函数按预期工作。但是,当我#include时,父类( Account.cpp )会因所有方法的Multiple definition of <method name>错误而破坏编译器。

同样,我不确定这是否是正确的方法,但这是我从我找到的教程中理解的。

代码

Account.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;
}

ChequingAccount.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.
        }
};

任何帮助将不胜感激!谢谢!

5 个答案:

答案 0 :(得分:1)

当你#include&#34;某些file.cpp&#34;时,你指示编译器将该cpp文件的内容复制到程序中的那一点。这将创建你的&#34;某个文件的两个编译版本&#34;这将导致多重定义。&#34;

答案 1 :(得分:0)

您在定义void Account::withdrawFunds(double)时已经定义了void ChequingAccount::withdrawFunds(double)

尝试virtual void ChequingAccount::withdrawFunds(double)

虚拟关键字类似于覆盖Java。

答案 2 :(得分:0)

首先,在基类和子类中声明的“相同”函数不会导致多个定义错误。

这里只是一个示例和解释,旨在帮助您理解我的观点:

的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。所以没有多重定义错误。再一次,在类声明中,您只能定义内联函数,并且只能声明非内联函数。因此,存在多个定义错误。这只是为了帮助您以语法方式理解它。

BTW,如果编译器无法内联,也不会出现多重定义错误,因为即使您在头文件中定义内联函数并将文件包含在任何地方,内联函数也是内部联系。

我编译了你的代码,并且对你定义的构造函数有不同的错误。无论如何,包括使用"include"的cpp文件意味着你没有得到实现文件和接口文件。

答案 3 :(得分:0)

简而言之,您不应该包含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的两个定义混淆,并且不知道使用哪个,所以它会开始抱怨。

答案 4 :(得分:0)

您还需要在子.cpp文件中显式声明子方法作为子类的成员。见下文:

ChequingAccount.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.
        }
};