c+中存在多个定义错误+;以及解决这个问题的办法 我是C++新手。对于C++中的多个定义错误,我有一些疑惑。

c+中存在多个定义错误+;以及解决这个问题的办法 我是C++新手。对于C++中的多个定义错误,我有一些疑惑。,c++,compiler-errors,linkage,multiple-definition-error,C++,Compiler Errors,Linkage,Multiple Definition Error,假设我在一个程序中有3个文件。一个头文件和2个.cpp文件。我已将头文件包含在两个.cpp文件中 我在头文件中声明了一个类,并且在每个.cpp文件中以完全相同的方式定义了该类。那么,这种类型的实现会导致多个定义错误吗?如果是这样,是不是因为它有两个类定义的副本,而编译器在链接两个.o文件时不知道使用哪一个 我们是否可以通过在头文件中使用extern并仅在其中一个文件中定义类来解决此问题?如果我们可以使用此方法解决此问题,是否必须将.cpp(带类定义)包含到其他.cpp文件中(不带类定义) 我已经

假设我在一个程序中有3个文件。一个头文件和2个.cpp文件。我已将头文件包含在两个.cpp文件中

  • 我在头文件中声明了一个类,并且在每个.cpp文件中以完全相同的方式定义了该类。那么,这种类型的实现会导致多个定义错误吗?如果是这样,是不是因为它有两个类定义的副本,而编译器在链接两个.o文件时不知道使用哪一个
  • 我们是否可以通过在头文件中使用
    extern
    并仅在其中一个文件中定义类来解决此问题?如果我们可以使用此方法解决此问题,是否必须将.cpp(带类定义)包含到其他.cpp文件中(不带类定义)

  • 我已经在头文件中声明并定义了一个类。这种情况与上述(1)相同吗

  • 我在头文件中声明了一个类,并在每个.cpp文件中定义了该类,但定义(函数体)不同。那么,这种类型的实现会导致多个定义错误吗?如果是这样,我们如何解决.cpp文件中函数体不同的问题

  • 1) 通过仅在一个cpp文件中“定义类”来解决此问题。为什么要在两个文件中定义它

    2) 不要在头文件中定义内容,只声明它们。此规则也有例外,例如内联函数。类本身也可以定义多次(我的意思是声明类的方法和数据成员,(即编写
    类XYZ{…};
    )但每个定义都必须相同。实现这一点的最简单方法是在头文件中定义一个类。然后,在多个位置包含该头文件所产生的每个定义都必须相同

    3) 这一次甚至更愚蠢,两次定义某件事是一回事,但定义两次,每次都不同,这就更没有意义了

    我想问题是为什么你认为有时有必要不止一次地定义事物。不要那样做

    您还应该明确“定义类”的含义。我认为这意味着定义类的方法和静态成员。但是如果你有别的想法,那可能会引起混乱。与往常一样,避免此类术语混淆的最佳方法是发布一些代码。

    1)项目中不能有同一类的两个定义。我不知道你打算怎么用它。如果要创建具有不同行为的一个类的实例,请使用虚拟函数,如:

    class A {
    public:
        virtual int foo() = 0;
    }
    
    class B : public A {
    public:
        virtual int foo() { return 1; }
    }
    
    class C : public A {
    public:
        virtual int foo() { return 2; }
    }
    
    2) 您可以在头文件(java样式)中定义类,但这不是最好的主意,因为编译器将消耗更多资源来构建其他文件,包括此头文件。让编译器快速工作-在.cpp文件中定义类


    3) 参见第1页要回答所有这些问题,您只需查看声明和定义的目的

    类的声明只是声明该类存在以及在哪个上下文中。对于一个类,一个简单的前向声明(例如
    classbanana;
    )允许您使用指向该类的指针或引用,但仅此而已

    定义准确地说明了类是什么。也就是说,它拥有哪些成员以及它是从哪些基类派生的。无论何时访问类的成员,或者需要知道其实例的大小,都需要使用此选项。这意味着类定义需要放在头文件中,以便它可以包含在使用该类的所有文件中的任何位置。这是可以的,因为标准规定一个类可以在多个翻译单元中定义,只要所有定义都相同

    类定义通常如下所示:

    class Banana
    {
    public: 
      Banana(){}
    
      void eat();
    
    private:
      //....
    };
    
    void C::f() {
        std::cout << "In C::f\n";
    }
    
    int C::j = 3;
    
    但是,请注意,此类定义仅表示类本身的定义,而不是非内联成员函数的定义。例如上面示例中的
    void eat()
    。这些需要在.cpp文件中定义,因为它们可能不在多个翻译单元中定义

    简言之:

  • 这是不对的,只在头文件中定义它,并在匹配的.cpp文件中定义非内联成员函数。绝不能在多个文件中定义相同的函数或类型
  • 只要在.cpp文件中单独定义成员函数,就可以了
  • 不,见1

  • 在几个地方定义一个类没有问题。这正是当您将定义放在一个标题中,并将该标题包含在多个源文件中时所发生的情况。但是,请注意,定义类意味着写出类包含的内容,而不是定义其成员。这是一个类定义:

    class C {
        void f();     // member function declaration
        void g() { }  // member function declaration with inline definition
        int i;        // member declaration
        static int j; // member declaration
    };
    
    与大多数情况一样,在单个源文件中不能多次定义它。但是,它可以出现在任意多个源文件中,只要它在任何地方都是相同的

    此类定义声明了两个必须在某处定义的成员,通常如下所示:

    class Banana
    {
    public: 
      Banana(){}
    
      void eat();
    
    private:
      //....
    };
    
    void C::f() {
        std::cout << "In C::f\n";
    }
    
    int C::j = 3;
    
    void C::f(){
    
    当然,类定义通常放在一个标题中,尽管标准要求它在每个翻译单元中都是相同的函数,但不是类本身。@Agentlien我不确定OP“定义类”是什么意思。正如我在回答中所说的,我认为他指的是定义类的方法。在额外阅读了一遍之后,我相信他实际上指的是类定义。无论他是否意识到这与定义成员函数之间的区别,我不能说。但是,您的回答清楚地表明(用相当苛刻的话),您不应该在头文件中定义类,这是不正确的。@Agentlien“相当苛刻的话”我很沮丧,