I am having a following situation:
#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;
}
One owner can have many items, but each item also must contain info about its owner. When I run this I get
Error C2027 use of undefined type 'Item'
I thought this would be solved by using forward class declarations, but no such luck. Also, I'm guessing my copy constructor and assignment operators are OK?
Forward declaring the type is only part of the solution. You also need move defintions of functions of at least one of the types when dependencies are circular - usually put in .cpp file (but not neccesary as seen in example).
Working example:
#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;
}
Furthermore, you copy the Items into the owner, so when you print the original, it only prints "Cup owned by " and "John", the owner, is missing. It's not clear which way this should be fixed - but could eg. be fixed by storing std::shared_ptr
instead if the items should be shared.