-4

假设我们有一个名为的类TestAPI和一个名为 的类UserAPI。类的一个对象UserAPI被创建并包含在类的头文件中TestAPI

现在,对象的实例UserAPI必须有权访问实例的私有成员变量,TestAPI但这不起作用,因为没有创建特定的对象。我希望我的库的用户在他们的代码 ( TestAPI) 中创建一个对象,以便稍后创建该对象。

例子:

main.cpp
{
    TestAPI test;
    test.User.SomeExampleToChangeRequest(); 
}

class TestAPI
{
    friend class UserAPI;
    public:
        UserAPI User;

    private:
        HINTERNET _hRequest;    // Variable which needs to be accessed from User    
};

现在来自类 UserAPI 的方法来更改请求句柄

UserAPI::SomeExampleToChangeRequest ()
{
    // how do I access _hRequest now? 
    // TestAPI._hRequest will not work since it's not static and class "global"
}

我该怎么做?将此定义为朋友仅适用于访问权限,并不能解决我的问题。

4

3 回答 3

1

在您对使用 C++ 进行面向对象设计的理解方面,有两个主要的改进领域。

  • 提供对私有成员的访问权限的首选应该是公共方法,而不是friend.
  • 要在方法中访问另一种类型的对象,您应该传递该类型的对象。不要开始考虑静态或全局对象,除非那是你真正想要的。

我在下面发布了一些代码片段。将它们放在一起解决您的问题。

class TestAPI {
public:
    // method to modify _hRequest
    void set_hRequest(HINTERNET& in_hRequest) {
        _hRequest = in_hRequest;
    }

    // method to access _hRequest
    HINTERNET& get_hRequest() {
        return _hRequest;
    }

private:
    HINTERNET _hRequest;
};

.

UserAPI::SomeExampleToChangeRequest(TestAPI& t) {
    // use 't' to access TestAPI here, like so ...
    HINTERNET h = t.get_hRequest();  
}

一旦你的用户创建了TestAPI对象,让他们通过引用UserAPI::SomeExampleToChangeRequest()方法来传递它。此外,使用 gbjbaanb 提到的前向声明来帮助编译器。

于 2013-10-21T13:40:34.110 回答
0

我认为解释为什么这不可能开箱即用的更清晰的方法是 UserAPI 的每个实例都不知道它是在哪里创建的或它的用途。

老实说,在这里有这样的直接链接,您可能需要在构造 UserAPI 以允许它调用 _hRequest 方法时为它提供某种“父”TestAPI 指针/引用。

编辑:

基本上将您对 UserAPI 的定义更改为以下内容:

// Forward declaration
class TestAPI;

class UserAPI
{
public:

    UserAPI( TestAPI* inParent )
    : m_parent ( inParent )
    {}

private:

    // Let's make this private to force construction with a TestAPI parent
    UserAPI(){}

    TestAPI* m_parent;
};

注意前向声明,因为编译器需要知道它的存在。如果您使用头文件,则将此声明放在 userAPI.h 的顶部,并且仅在 userAPI.cpp 中包含 testAPI.h。

请记住,这将不允许您从 userAPI.h 中调用任何 TestAPI 函数,但它将在 userAPI.cpp 中提供完全访问权限

因此UserAPI::SomeExampleToChangeRequest需要在 userAPI.cpp 中定义

UserAPI::SomeExampleToChangeRequest ()
{
    // The TestAPI variable or function can now be accessed like so
    m_parent->_hRequest;
}

最后一点提示:如果您不想使用单独的头文件和 cpp 文件,那么只要您UserAPI::SomeExampleToChangeRequest在定义 TestAPI 之后进行定义,那么您就可以开始使用了。

最后一点:正如 Happy 所说,朋友并不是真正需要的,应该在面向对象的 C++ 中谨慎使用。最好创建一个公共函数来访问该参数

于 2013-10-21T09:58:29.817 回答
0

您可以创建一个前向声明,这是一种表示“稍后将提供此定义”的方式,因此您的代码将正确检查语法,并且编译器稍后会为您解决问题(它知道两个类的完整定义) .

但是,有一些限制。因为编译器对前向声明的类一无所知,所以您不能引用它的方法或它的大小。这意味着您几乎必须通过指针来引用它,您希望将其包装在智能指针中。

于 2013-10-21T13:22:23.580 回答