3

例子:

H

class MyClass {
    int x,y,z;
public:
    MyClass(int,int,int);
    void X();
    void Y();
    void Z();
};

CPP

class MyClass {
    int x,y,z;
public:
    MyClass(int x,int y,int z) {
        this->x=x;
        this->y=y;
        this->z=z;
    }
    void X() {
        printf("x = %d;\n",x);
    }
    void Y() {
        printf("y = %d;\n",y);
    }
    void Z() {
        printf("z = %d;\n",z);
    }
};

使其类似于 C#。不要包含标题,在 CPP 中重新声明类,但使用方法体。当文件包含标题时,他会从 CPP 获取外部字段\方法等。

合法吗?我无法从中预测问题。有?

4

3 回答 3

11

这属于单一定义规则的领域。特别是,对同一类的单个程序的多个 TU 的多个定义提出的要求是:

[...] — D 的每个定义都应包含相同的标记序列 [...]

(3.2 第 5 段一个定义规则 [basic.def.odr])

因此,即使您“修复”第一个版本以声明成员函数inline以匹配第二个版本(提供成员的定义隐式声明它们inline),您仍然会违反此规则:函数体是出现在一个,但不在另一个。

于 2012-10-11T14:54:21.237 回答
5

单定义规则部分的 3.2/5 不允许这样做。

一个类类型可以有多个定义(第 9 条),...[其他无关紧要的类型和条件]

...并提供定义满足以下要求。给定这样一个名为 D 的实体在多个翻译单元中定义,则

-- D 的每个定义应由相同的标记序列组成;

如果标头包含在任何其他链接的翻译单元中,这显然会禁止这种机制。

如果您想编写 C#,只需用 C# 编写即可。如果您编写惯用的 C++ 而不是方言,您未来的维护者将非常感激。

于 2012-10-11T14:51:58.000 回答
-1

一个主要问题是循环引用:如果 class 的代码A包含 class 的实例B,而该实例本身使用 class A,编译将失败。

将一个类分成其声明 (.h) 和定义 (.cpp) 可解决此问题。

但是:如果您仍然想将类定义放在头文件中,您可以通过将类设置为模板来实现,从而有效地推迟类型解析。但这是以增加编译时间为代价的!

于 2012-10-11T14:54:27.980 回答