Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/126.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 您如何实施;“授权”;对于C+中的类+;?_C++_Delegation - Fatal编程技术网

C++ 您如何实施;“授权”;对于C+中的类+;?

C++ 您如何实施;“授权”;对于C+中的类+;?,c++,delegation,C++,Delegation,在Objective C中,该语言支持将类委托给其他类。C++没有这样的特性(一个类作为另一个类的代表)作为语言的一部分。模仿的一种方法是以这种方式分离声明和实现: 在头文件a.h中: 在.cpp(实现文件)中: 这需要在类中手动创建所有“转发器”函数,这些函数将委托给另一个类来执行实际工作。至少可以说是乏味的 问题是:使用模板或其他C++语言构造有更好的或更有效的方法来实现这个效果吗?< P>你可以在基类中实现一个虚拟接口。 但是,如果确实要委派,则可以重载操作符->以委派所有呼叫。 您不再

在Objective C中,该语言支持将类委托给其他类。C++没有这样的特性(一个类作为另一个类的代表)作为语言的一部分。模仿的一种方法是以这种方式分离声明和实现:

在头文件a.h中:

在.cpp(实现文件)中:

这需要在类中手动创建所有“转发器”函数,这些函数将委托给另一个类来执行实际工作。至少可以说是乏味的


问题是:使用模板或其他C++语言构造有更好的或更有效的方法来实现这个效果吗?

< P>你可以在基类中实现一个虚拟接口。 但是,如果确实要委派,则可以重载
操作符->
以委派所有呼叫。
您不再需要转发方法:

#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();
}
#包括
#包括
使用名称空间std;
AImpl类;
甲级
{
公众:
A();
//重载操作符->将调用委托给AImpl类
AImpl*运算符->()常量{return mImpl;}
私人:
AImpl*mImpl;
};
类AImpl
{
公众:
void f1(){std::cout f2();
}

是的,这是可能的。一个可能的例子是:

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;
};
结构WidgetDelegate { 虚拟~WidgetDelegate(){} 虚拟void onNameChange(std::string newname,std::string oldname){} }; 类小部件 { 公众: std::共享的ptr委托; 显式小部件(std::string name):m_name(name){} void setName(std::string name){ if(delegate)delegate->onNameChange(name,m_name); m_name=名称; } 私人: std::字符串m_名称; }; 用法:

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;
}
类MyWidgetDelegate:公共WidgetDelegate
{
公众:
虚拟void onNameChange(std::string newname,std::string oldname){

std::cout代替所有这些转发,您只需在标头中声明一个纯接口,再加上一个工厂函数的声明。在实现文件中,一个实现接口的类,以及工厂的实现。假设客户端代码不应该有意义地扩展该类。我认为没有但我会等待一个比我更有知识的人来纠正我。我准备写一个完整的清单,说明如何在C++中赋值函数,但是我发现有人已经这样做了:投票以重复的方式关闭我的问题。我特别感兴趣的是类级委托,而不是函数级委托。e> 一个
当它不是指针时,就好像它是一个指针,这有点违反直觉,我想它不会帮助代码的读者/维护者。
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>