如何解决这个前向 class 声明问题?

How to solve this forward class declaration problem?

我遇到以下情况:

#include <iostream>
#include <vector>
#include <string>
using namespace std;

// Forward declarations
class Owner;
class Item;

class Owner {
public:
    string name;
    vector<Item> item;
    Owner(string _name, initializer_list<Item> _item) : name(_name), item(_item) {
        for (size_t i = 0; i < item.size(); i++)
            item[i].owner = this;
    }
    // change the owner when copying...
    Owner(const Owner& o) {
        name = o.name;
        item = o.item;
        for (size_t i = 0; i < item.size(); i++)
            item[i].owner = this; // is this OK? 
    }
    Owner& operator = (const Owner& o) {
        name = o.name;
        item = o.item;
        for (size_t i = 0; i < item.size(); i++)
            item[i].owner = this; 
        return *this;
    }
};
class Item {
public:
    string name;
    Owner* owner;
    Item(string _name) : name(_name) {}
    string getInfo() {
        return name + " owned by " + owner->name;
    }
};
int main(){
    Item Cup("Cup"), Plate("Plate");
    Owner John("John", { Cup, Plate });
    cout << Cup.getInfo() << endl; // expecting "Cup owned by John"
    return 0;
}

一个所有者可以拥有多个项目,但每个项目还必须包含有关其所有者的信息。当我 运行 这个我得到

Error C2027 use of undefined type 'Item'

我认为这可以通过使用前向 class 声明来解决,但没有这样的运气。另外,我猜我的复制构造函数和赋值运算符没问题?

当你使用std::vector<Item>时,Item必须是一个完整的类型。在这种情况下,您只在 Item 中使用 Owner*,因此 Item 应该放在第一位。 由于您在 getInfo() 中取消引用 Owner*,因此它的定义应该在 Owner class:

之后
class Owner;

class Item {
    // ...
    std::string getInfo() const;
};

class Owner {
    // ...
};

std::string Item::getInfo() const
{
    // return ...
}

转发声明类型只是解决方案的一部分。当依赖项是循环的时,您还需要移动至少一种类型的函数定义 - 通常放在 .cpp 文件中(但不是必需的,如示例中所示)。

工作示例:

#include <iostream>
#include <vector>
#include <string>
using namespace std;

// Forward declarations
class Owner;

class Item {
public:
    string name;
    Owner* owner;
    Item(string _name) : name(_name) {}
    string getInfo();//<-- only declaration now
};

class Owner {
public:
    string name;
    vector<Item> item;
    Owner(string _name, initializer_list<Item> _item) : name(_name), item(_item) {
        for (size_t i = 0; i < item.size(); i++)
            item[i].owner = this;
    }
    // change the owner when copying...
    Owner(const Owner& o) {
        name = o.name;
        item = o.item;
        for (size_t i = 0; i < item.size(); i++)
            item[i].owner = this; // is this OK? 
    }
    Owner& operator = (const Owner& o) {
        name = o.name;
        item = o.item;
        for (size_t i = 0; i < item.size(); i++)
            item[i].owner = this; 
        return *this;
    }
};

//or put in .cpp file
    string Item::getInfo() {
        return name + " owned by " + owner->name;
    }

int main(){
    Item Cup("Cup"), Plate("Plate");
    Owner John("John", { Cup, Plate });
    cout << Cup.getInfo() << endl; // expecting "Cup owned by John"
    return 0;
}

Try it yourself

此外,您将项目复制到所有者中,因此当您打印原件时,它只会打印所有者"Cup owned by "和"John",不见了。目前尚不清楚应该以哪种方式解决这个问题 - 但可以例如。如果项目应该共享.

,则通过存储 std::shared_ptr 而不是 来修复