Как передать один объект другому с помощью ключевого слова this без ошибок предварительного объявления

Это мой первый пост, поэтому будьте осторожны со мной 🙂 Я пытаюсь передать объект другому объекту, объявленному в первом объекте, с помощью ключевого слова this. Все идет хорошо, пока я не попытаюсь получить доступ к чему-либо из первого объекта, который я передал во втором объекте. Я получаю следующие ошибки:

cac.cc: In member function ‘void Portfolio::check(Client*)’:
cac.cc:8:9: error: invalid use of incomplete type ‘struct Client’
cac.cc:3:7: error: forward declaration of ‘struct Client’

Вот код ниже, я также сузил его до строки, на которой он терпит неудачу. Если я закомментирую эту строку, код скомпилируется:

#include <iostream>

class Client;

class Portfolio {
public:
void check(Client *client) {
client->buy("AAPL");   //<- If i comment our this line the program compiles
}
};

class Client {
public:
Portfolio port;

void buy(std::string name) {
std::cout << "Sending order for " << name << "!\n";
}

void shouldIBuy() {
port.check(this);
}
};

int main() {
Client client;
client.shouldIBuy();
}

Я полагаю, что код не компилируется, потому что, хотя класс Client был создан прототипом, его функция-член buy не имеет. Может ли кто-нибудь с большим опытом, чем я, подтвердить это. Любые возможные способы обойти это без изменения структуры слишком много?

Спасибо!

0

Решение

Стандартный подход заключается в отделении реализации от деклараций. Это гарантирует, что объявление класса доступно для всех модулей реализации. В более крупной программе каждый логический сегмент (потенциально каждый класс) будет находиться в одной единице компиляции. Ниже приведена многоэлементная реализация с некоторыми комментариями, поясняющими более мелкие детали.

// -- this be in "client.h"#include <string>
#include "portfolio.h"
class Client {
public:
void buy(std::string const& name);
bool shouldIBuy();
private:
// since Portfolio is include by value (not a pointer), the
// compiler absolutely requires that it is a "complete type"// so that it can calculate the correct byte size of a Client
// object
Portfolio port;
};// -- the following would be in "portfolio.h"// Client is only referenced in a parameter list so a complete
// type is unnecessary.  A forward declaration is the "least
// coupled" solution.
class Client;

class Portfolio {
public:
bool check(Client *client);
};// -- the following would be in "client.cpp"#include <iostream>

#include "client.h"#include "portfolio.h"
void Client::buy(std::string const& name) {
std::cout << "Sending order for " << name << "!\n";
}

bool Client::shouldIBuy() {
return port.check(this);
}// -- the following would be in "portfolio.cpp"#include "portfolio.h"#include "client.h"
bool Portfolio::check(Client *client) {
// we need the complete type of Client at this point
client->buy("AAPL");
return true;
}// -- the following would be in "main.cpp"#include "client.h"
int main() {
Client client;
client.shouldIBuy();
return 0;
}
0

Другие решения

Подождите с определением функции-члена до окончания класса Client было определено:

class Client;

class Portfolio {
public:
void check(Client *client);
};

class Client {
public:
Portfolio port;

void buy(std::string name) {
std::cout << "Sending order for " << name << "!\n";
}

void shouldIBuy() {
port.check(this);
}
};

void Portfolio::check(Client *client) {
client->buy("AAPL");
}
4

По вопросам рекламы [email protected]