类原型创建c ++

Cod*_*de0 1 c++ prototype class

#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;
}
Run Code Online (Sandbox Code Playgroud)

我知道有很多这样的帖子,但是他们似乎都没有解决我的错误Variable has incomplete type (class_name_here).

我想要做的就是,在主块之后创建类,并通过在主块之前创建"原型"来完全使用它.我想:嗯,这很简单,但是无法修复它.

cdh*_*wie 5

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

您不能声明不完整类型的变量.这是因为编译器需要知道为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;
}
Run Code Online (Sandbox Code Playgroud)

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

class Parent;

class Child {
private:
    Parent & parent;
};

class Parent {
private:
    std::vector<Child> children;
};
Run Code Online (Sandbox Code Playgroud)

这种技术也被opaque指针idiompimpl模式使用,在这种模式中,您将类中的所有数据成员存储在另一个对象中,该对象的类型不会暴露给使用它的代码.这允许您在不破坏代码的二进制接口的情况下更改数据成员.(通常情况下添加或删除或改变一个数据成员会导致类的对象改变的大小和/或布局,例如这种方法会导致尺寸保持恒定;你只是一个指针存储到数据,并且将数据课程可以在不让消费者知道或关心的情况下改变布局.)

class Something {
private:
    class Data;
    std::unique_ptr<Data> data;
};
Run Code Online (Sandbox Code Playgroud)

使用您的库的代码不知道Something::Data它是什么,但它不需要关心.然后在您的实现文件中为Something您定义此类.

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