我是C ++抽象类的新手,我正在努力学习如何使用它。所以我开始定义一个只有纯函数的抽象类,让我们调用这个类SceneObj
,到目前为止一直很好。之后,我首先定义一个我正在调用IScreen
的新抽象类;这个新的Class
也是另一个抽象类,但它增加了新的要求。
不幸的是,在尝试编译这个简单的代码时,我遇到了以下错误:error C2011: 'IScreen' : 'class' type redefinition
。
我正在使用Visual Studio 2012,我正在尝试编译的代码如下:
#include <stdlib.h>
using namespace std;
class SceneObj
{
protected:
float center;
public:
virtual void SetCenter(float,float,float) = 0;
virtual void SetCenter(float) = 0;
virtual float GetCenter() = 0;
virtual ~SceneObj();
};
class IScreen : public SceneObj
{
public:
virtual void SetCenter(float,float,float) = 0;
virtual void SetCenter(float) = 0;
virtual float GetCenter() = 0;
virtual float GetStartCorner() = 0;
virtual void SetSize(float,float) = 0;
virtual void SetSize(long) = 0;
virtual long GetSize() = 0;
virtual ~IScreen();
};
有人能指出我这个代码中的缺陷是什么/哪里?
编辑:将代码更改为最小代码
edit2:这是header file
,显然如果我将其更改为.cpp
,它会毫无问题地编译。但我需要/想要在headers
中声明我的课程然后在.cpp
中定义。
答案 0 :(得分:1)
C ++程序还使用预处理器来定义标头保护。头卫
依赖预处理器变量。预处理器变量有两个之一
可能的状态:已定义或未定义。 #define
指令采用名称和定义
该名称作为预处理器变量。还有另外两个指令可以测试是否
已定义或尚未定义给定的预处理器变量:#ifdef
如果变量为真
已定义,如果尚未定义变量,则#ifndef
为真。如果测试是
是的,那么#ifdef
或#ifndef
之后的所有内容都会被处理完毕
匹配#endif
。
我们可以使用这些设施来防止多重包含,如下所示:
#ifndef SALES_DATA_H
#define SALES_DATA_H
#include <string>
struct Sales_data {
std::string bookNo;
unsigned units_sold = 0;
double revenue = 0.0;
};
#endif //SALES_DATA_H
答案 1 :(得分:0)
例如,在头文件中,您将找到类似下面的内容:
#ifndef __*__SceneObj
#define __*__SceneObj__
//Place the abstract class here
#endif
所以你必须把抽象类放在#define和#endif之间。 (这是编译器将考虑的定义)。你只是在cpp文件上没有这些礼节。这就是它在那里工作的原因。 另外,尝试每个头文件有一个类,因此不要在同一个头文件中声明子类。
答案 2 :(得分:-2)
这意味着您已经定义了类型IScreen的某个地方。通常,编译器会提供对重复定义的引用。
因此请调查错误消息。
至于你的代码片段,那就无关紧要了。
如果发现错误,MS VS通常会发出几条消息。
另一个原因可能是您在带有main的模块中包含带有成员函数定义的cpp模块。
例如
头文件:header.h
#include <stdlib.h>
using namespace std;
class SceneObj
{
//...
};
class IScreen : public SceneObj
{
//...
};
带成员函数定义的cpp模块:module,cpp
#include "header.h"
//...
带主
的模块#include "header.h"
#include "module.cpp"
//...
还包括指令
#pragma once
在你的头文件中。