如何使用this关键字将一个对象传递给另一个对象而没有前向声明错误

时间:2014-04-05 13:21:33

标签: c++ this prototyping

这是我的第一篇文章,所以对我很容易:-)我试图使用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也没有。任何比我更有经验的人都能证实这一点。没有改变结构的任何可能的方法吗?

谢谢!

2 个答案:

答案 0 :(得分:4)

等待成员函数定义,直到定义了类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");
}

答案 1 :(得分: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;
}