簡體   English   中英

您如何在C ++中為類有效地實現“委托”?

[英]How do you implement “delegation” for classes efficiently in C++?

在Objective C中,該語言內置了將類委派給其他類的支持。 C ++沒有作為語言一部分的這種功能(一個類作為另一個類的委托)。 一種模仿的方法是將聲明和實現分開:

在頭文件ah中

class AImpl;

class A
{
public:
     A();

     void f1();
     int f2(int a, int b); 
     // A's other methods...
private:
    AImpl *mImpl;
};

.cpp (實現文件)中:

#include "a.h"

class AImpl
{
public:
     AImpl();
     // repeating the same method declarations from A
     void f1();
     int f2(int a, int b); 
     // AImpl's other methods
};

AImpl::AImpl()
{
}

void AImpl:f1()
{
    // actual implemetation
}

int AImpl::f2(int a, int b)
{
    // actual implmentation
}

// AImpl's  other methods implementation

A::A()
{
     mImpl = new AImpl();
}

// A's "forwarder"

void A::f1()
{
    mImpl->f1();
}

int A::f2(int a, int b)
{
    return mImpl->f2(a, b);
}

// etc.

這需要在類中手動創建所有“轉發器”函數,這些函數將委派給另一個類以進行實際工作。 至少可以說是乏味的。

問題是:是否有使用模板或其他C ++語言構造實現此效果的更好或更有效的方法?

是的,有可能。 可能的示例之一是:

struct WidgetDelegate
{
    virtual ~WidgetDelegate() {}
    virtual void onNameChange(std::string newname, std::string oldname) {}
};

class Widget
{
public:
    std::shared_ptr<WidgetDelegate> delegate;
    explicit Widget(std::string name) : m_name(name){}
    void setName(std::string name) {
        if (delegate) delegate->onNameChange(name, m_name);
        m_name = name;
    }
private:
    std::string m_name;
};

用法:

class MyWidgetDelegate : public WidgetDelegate
{
public:
    virtual void onNameChange(std::string newname, std::string oldname) {
        std::cout << "Widget old name: " << oldname << " and new name: " << newname << std::endl;
    }
};

int main()
{
    Widget my_widget("Button");
    my_widget.delegate = std::make_shared<MyWidgetDelegate>();
    my_widget.setName("DoSomeThing");   
    return 0;
}

必需包括:

#include <string>
#include <iostream>
#include <memory>

您可以在基類中實現虛擬接口。
但是,如果您確實要委托,則可以重載operator->以委托所有調用。
您將不再需要轉發方法:

#include <iostream>
#include <string>

using namespace std;

class AImpl;

class A
{
    public:
        A();

        //Overloading operator -> delegates the calls to AImpl class
        AImpl* operator->() const { return mImpl; }

    private:
        AImpl *mImpl;
};

class AImpl
{
    public:
        void f1() { std::cout << "Called f1()\n"; }
        void f2() { std::cout << "Called f2()\n"; }
};

A::A()
{
    mImpl = new AImpl();
}

int main()
{
    A a;
    a->f1(); //use a as if its a pointer, and call functions of A

    A* a1 = new A();
    (*a1)->f2();
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM