从同一个父调用

时间:2018-01-23 21:48:41

标签: c++

考虑这个简单的C ++ 11继承示例:

class A
{
public:
    virtual void func() = 0;
};

class B : public A
{
public:
    void func() { func1(); /* Wish this could be func1() or func2()! */ };

    void func1() { /* Does one thing */ };
    void func2() { /* Does another thing */ };
};

void doSomeStuff(A &a) 
{
    a.func();
}

int main()
{
    B b;

    doSomeStuff(b);

    return 0;
}

我正在尝试这样做,以便我不必修改(或复制)类A的定义或函数doSomeStuff,但我希望调用a.func()来调用func1()或func2 B的()理想情况下,我会将doSomeStuff(b)行更改为类似doSomeStuff(b.butWithFunc1)的内容,但我也可以通过某种方式修改B的func()版本,以便它可以内部根据某些参数调用func1func2的决定。

在调用func1期间,类型B的同一对象有时可能必须调用func2func,因此我不能使用B类的持久成员来决定。向func()添加一个参数也会使这个变得微不足道,但这不是我能做的事情。

我有点想知道是否有一些方法可以向B类添加一个返回B类变异版本的函数,该函数从func()调用func2(),或者我可以使用函数指针或某些东西来玩一些技巧。然而,有些东西告诉我,我做错了,显而易见的解决方案就是盯着我。

如果它对上下文有帮助,那么类A类似于std :: lock_guard,它适用于信号量和互斥量之类的东西(其中只有一个锁和解锁的定义),但在这个例子中是B类是一个R / W锁 - 所以有一个“readLock”和“writeLock”,我希望能够说“自动锁定这个RW锁作为读锁”,而不必复制/破坏自动锁定代码。

例如:

{
    A_AutoSem(myMutex); // calls lock() on myMutex
    //... do some stuff

    // end of the block, ~A_AutoSem calls unlock on myMutex
}

{
    A_AutoSem(B_RWLock); // how do I say here "call readLock"?
    // ... do some stuff

    // end of the block ~A_AutoSem should call "readUnlock" on B_RWLock
}

1 个答案:

答案 0 :(得分:2)

只需定义一些其他类即可调用func1()func2(),然后将这些类传递给doSomeStuff(),而不是直接传递B

尝试这样的事情:

class A
{
public:
    virtual void func() = 0;
};

class B
{
public:
    void func1() { /* Does one thing */ };
    void func2() { /* Does another thing */ };
};

class C1 : public A
{
private:
    B &m_b;
public:
    C1(B &b) : m_b(b) {}
    void func() override { m_b.func1(); }
};

class C2 : public A
{
private:
    B &m_b;
public:
    C2(B &b) : m_b(b) {}
    void func() override { m_b.func2(); }
};

void doSomeStuff(A &a) 
{
    a.func();
}

int main()
{
    B b;

    {
    C1 c(b);
    doSomeStuff(c);
    }

    {
    C2 c(b);
    doSomeStuff(c);
    }

    return 0;
}

Live Demo

可替换地:

class A
{
public:
    virtual void func() = 0;
};

class B
{
private:
    void func1() { /* Does one thing */ };
    void func2() { /* Does another thing */ };

public:
    class C1 : public A
    {
    private:
        B &m_b;
    public:
        C1(B &b) : m_b(b) {}
        void func() override { m_b.func1(); }
    };

    class C2 : public A
    {
    private:
        B &m_b;
    public:
        C2(B &b) : m_b(b) {}
        void func() override { m_b.func2(); }
    };
};

void doSomeStuff(A &a) 
{
    a.func();
}

int main()
{
    B b;

    {
    B::C1 c(b);
    doSomeStuff(c);
    }

    {
    B::C2 c(b);
    doSomeStuff(c);
    }

    return 0;
}

Live Demo