我制作了一个较小的可复制版本的代码,使我犯了这些错误:'MyNamespace::MySecondClass': 'class' type redefinition
,'print': is not a member of 'MyNamespace::MySecondClass'
。有什么办法可以解决这个问题?
// MyClass.h
#pragma once
namespace MyNamespace {
class MySecondClass {};
}
// MyClass.cpp
#include "MyClass.h"
#include <iostream>
using namespace std;
class MyNamespace::MySecondClass
{
public:
void print(const char* msg)
{
cout << msg << endl;
}
};
答案 0 :(得分:3)
问题在于,您在MyClass.h
中将类MySecondClass
定义为空类。当您在MyClass.cpp中定义类时,您将给出不同的定义,其中包含一些新成员。这违反了一个定义规则(ODR)。
删除标题中的{}
。这将告诉编译器您声明存在此类,但稍后将对其进行定义。您的代码将编译。不幸的是,如果您将标头包含在其他cpp中,则这些标头只能非常有限地使用MySecondClass
。
在标头中定义包含所有成员的类(但不提供成员函数的实现:签名就足够了)。这将允许在任何cpp中使用该类 将包括它:
// MyClass.h
#pragma once
namespace MyNamespace {
class MySecondClass {
public:
void print(const char* msg);
};
}
然后,您可以在相应的命名空间的cpp中定义该类的成员:
// MyClass.cpp
#include <iostream>
#include "MyClass.h"
using namespace std;
namespace MyNamespace {
// member functions
void MySecondClass::print(const char* msg)
{
cout << msg << endl;
}
}
备注:cpp中的include序列应首先包含标准库头,然后仅包含您自己的头。在您的简单示例中没有什么区别,但是最好立即使用良好实践。