考虑这个简单的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()
版本,以便它可以内部根据某些参数调用func1
或func2
的决定。
在调用func1
期间,类型B的同一对象有时可能必须调用func2
或func
,因此我不能使用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
}
答案 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;
}
可替换地:
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;
}