首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >这里有比朋友课更好的方式吗?

这里有比朋友课更好的方式吗?
EN

Stack Overflow用户
提问于 2013-02-05 06:29:40
回答 4查看 132关注 0票数 1

尽管这种情况在任何地方都可能发生,但在C++ for Windows中编程。这是我的问题的一个简化版本,以保持问题的可管理性,所以不要过于关注细节:)

我有一个包含windows HWND数据项的类class Window。我希望完全封装该HWND,以便类的用户必须通过类才能在该窗口上执行任何操作,因此它被存储在私有成员变量中。我不想为它提供任何公共的"getter“,因为这会破坏允许用户绕过我的类的封装。

现在我想创建一个类class Direct3d11来封装一些directx api。为了创建这个类的实例,它需要一个窗口的HWND,所以我在它的构造函数中给它传递了一个Window对象。

代码语言:javascript
复制
class Direct3D11
{
public:
    Direct3D11(const Window& window);
};

在构造函数内部,它可以访问窗口对象,但是它需要包含在其中的HWND,以便能够物理地创建Direct3D11类将管理的窗口对象,但是它没有办法获得该信息。

我可以添加一个私有的getter函数来获取Window类的HWND,然后使Direct3D11类成为Window的友元类,这样它就可以调用该函数。

然而,这看起来并不是很优雅,尤其是因为类窗口在其他方面根本不需要了解类Direct3D11的任何信息。

我是不是错过了一个更好的方法来实现这一点?Friend类没有吸引力,拥有一个公共的getter函数也没有多大吸引力。

EN

回答 4

Stack Overflow用户

发布于 2013-02-05 06:33:49

您可以在Window中创建Direct3D11类,因为Windows拥有HWND

大致是这样的:

代码语言:javascript
复制
class Window
{
    HWND hwnd;
    Direct3D11 d;
public:
    Window() : d(hwnd) {}
    Direct3D11& getDirect3D()
    {
       return d;
    }
}
票数 3
EN

Stack Overflow用户

发布于 2013-02-05 06:45:25

你可以在Window上使用一个名为Execute的函数。它将接受一个std::函数,并将HWND的占位符作为参数。然后,Window将使用HWND作为其唯一参数来调用该函数。

这将需要c++11,但代码将类似于:

代码语言:javascript
复制
#include <functional>
#include <iostream>

struct Foo {
    explicit Foo(int num) : num_(num) {}
    template<typename T>
    void execute(std::function<T> f) const { f(num_); }
    private:
    int num_;
};

struct Bar{
    void print_nums(int i,int j)
    {
        std::cout << "i:" << i << ", " << "j:" << j << std::endl;
    }
};

int main()
{
    Foo o(42);
    Bar b;

    //the function we want to execute requires an int
    //that Foo knows about
    typedef void myFunction(int);

    // store the result of a call to std::bind
    std::function<myFunction> display_1337_first = std::bind(&Bar::print_nums, b,1337, std::placeholders::_1);
    std::function<myFunction> display_1337_last = std::bind(&Bar::print_nums, b, std::placeholders::_1, 1337);
    o.execute<myFunction>(display_1337_first);
    o.execute<myFunction>(display_1337_last);
    return 0; 
}

//output:
//i:1337, j:42
//i:42, j:1337
票数 1
EN

Stack Overflow用户

发布于 2013-02-05 06:50:18

在您的情况下,我建议为HWND提供一个getter,因为您可能会更经常地需要它。提供getter并不意味着你要承担你的窗口类的责任,它仍然负责窗口的生命周期。你只是让它更易用,更容易在用例中划分你的代码。

也就是说,这里有一种更通用的方法,您可以尝试一下:

代码语言:javascript
复制
class Window;

class Direct3D {
public:
    void apply(Window &window, HWND hWnd);
};

class Window {
public:
    void accept(Direct3D &direct3d) {
        direct3d.apply(*this, this->m_hWnd);
    }
};
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14696938

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档