How to pass one object to another using the this keyword without forward declaration errors

StackOverflow https://stackoverflow.com/questions/22881447

  •  28-06-2023
  •  | 
  •  

Frage

This is my first post so go easy on me :-) I am trying to pass an object to a different object declared within the first object using the this keyword. It all goes well until I try and access something from the first object I passed in the second object. I end up with the following errors:

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’

Here's the code below, I also narrowed it down to the line it fails on. If I comment out this line the code compiles:

#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();
}

I believe the code is failing to compile because, even though the Client class has been prototyped, it's member function buy has not. Can anyone with more experience than me confirm this. Any possible ways around this without changing the structure too much?

Thanks!

War es hilfreich?

Lösung 2

The standard approach is to separate the implementation from the declarations. This ensures that the class declaration is available to all implementation modules. In a larger program, each logical segment (potentially each class) would be in its one compilation unit. The following is a multi-unit implementation with some comments explaining the finer details.

// -- 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;
}

Andere Tipps

Wait with the member function definition until after the class Client has been defined:

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");
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top