c++ - 类原型(prototype)创建 C++

标签 c++ class prototype

#include <iostream>    
using namespace std;

class Rectangle;

int main () {
    Rectangle rect (3,4);
    Rectangle rectb (5,6);
    cout << "rect area: " << rect.area() << endl;
    cout << "rectb area: " << rectb.area() << endl;
    return 0;
}

class Rectangle {
    int width, height;
public:
    Rectangle (int,int);
    int area () {return (width*height);}
};

Rectangle::Rectangle (int a, int b) {
    width = a;
    height = b;
}

我确实知道有很多这样的帖子,但是它们似乎都没有修复我的错误Variable has incomplete type (class_name_here)

我想要做的就是在主 block 之后创建类,并通过在主 block 之前创建“原型(prototype)”来充分使用它。我想:好吧,这很简单,但就是无法修复它。

最佳答案

类型的前向声明创建了所谓的不完整类型 -- 已知存在的类型,但其特征尚不清楚。

您不能声明不完整类型的变量。这是因为编译器需要知道为 Rectangle 对象分配多少空间,以及该类型存在哪些构造函数。请注意,您也无法在对象上调用 area(),因为编译器尚未看到该方法的声明。

可以声明指向引用不完整类型的变量,但实际上您不能对它们做任何事情,除了指针或引用的简单赋值,或将它们传递给接受指针/引用的其他函数,直到类型完成。

class Rectangle;

Rectangle & get_rectangle();

int main(void) {
    // OK, this is a reference.
    Rectangle & r = get_rectangle();

    // OK, this is a pointer.
    Rectangle * rp = &r;

    // Not OK; the compiler doesn't know (a) how much space to allocate on the stack,
    // nor (b) if the type has a default constructor.
    Rectangle rect;

    // Not OK; the compiler has not seen a declaration of Rectangle so it doesn't know
    // whether the area() method exists, nor its signature.
    r.area();
    rp->area();

    return EXIT_SUCCESS;
}

通常,当类型之间存在某种循环依赖时,您会使用类型的前向声明,例如,某些子节点类型需要引用其父节点,但父类型包含子节点。

class Parent;

class Child {
private:
    Parent & parent;
};

class Parent {
private:
    std::vector<Child> children;
};

不透明指针惯用语pimpl 模式 也使用了这种技术,您可以将类中的所有数据成员存储在另一个对象中,而该对象的类型不公开使用它的代码。这允许您在不破坏代码的二进制接口(interface)的情况下更改数据成员。 (例如,通常添加、删除或更改数据成员会导致类对象的大小和/或布局发生变化。这种方法会导致大小保持不变;您只需存储一个指向数据的指针,而 < em>data 类可以在您的消费者无需知道或关心的情况下更改布局。)

class Something {
private:
    class Data;
    std::unique_ptr<Data> data;
};

使用您的库的代码不知道Something::Data 是什么,但它不必关心。然后在 Something 的实现文件中定义这个类。

在您的情况下,没有理由使用前向声明。只需将前向声明替换为实际的类定义即可。

关于c++ - 类原型(prototype)创建 C++,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26660012/

相关文章:

c++ - "(void)!ptr"是做什么的?

c++ - 静态全局函数的静态局部成员?

c++ - 是否可以在 C++ 中创建 "friend class"?

javascript - 这是正确的(JavaScript 原型(prototype)属性)吗?

c++ - 为什么输入时忽略前导零?

java - 在java中将类内容打印到控制台

C++ Windows 应用程序窗体无法进行转发声明

javascript - 扩展 JavaScript?

javascript - 属性复制到继承类型的目的

c++ - 为什么 basic_string::append (iter, iter) 不调用 std::copy?