gpt4 book ai didi

c++ - 虚拟继承和静态继承——C++中的混合

转载 作者:可可西里 更新时间:2023-11-01 16:41:38 25 4
gpt4 key购买 nike

如果你有这样的事情:

#include <iostream>

template<typename T> class A
{
public:
void func()
{
T::func();
}
};

class B : public A<B>
{
public:
virtual void func()
{
std::cout << "into func";
}
};

class C : public B
{
};

int main()
{
C c;
c.func();

return 0;
}

func() 是动态调度的吗?
您如何实现类 A,以便在 B 具有虚拟重写时动态分派(dispatch)它,但如果 B 没有,则静态分派(dispatch)?

编辑:我的代码没有编译?对不起大家。我现在有点不舒服。我的新代码也无法编译,但这是问题的一部分。另外,这个问题是给我的,不是常见问题解答。

#include <iostream>

template<typename T> class A
{
public:
void func()
{
T::func();
}
};

class B : public A<B>
{
public:
virtual void func()
{
std::cout << "in B::func()\n";
}
};

class C : public B
{
public:
virtual void func() {
std::cout << "in C::func()\n";
}
};
class D : public A<D> {
void func() {
std::cout << "in D::func()\n";
}
};
class E : public D {
void func() {
std::cout << "in E::func()\n";
}
};

int main()
{
C c;
c.func();
A<B>& ref = c;
ref.func(); // Invokes dynamic lookup, as B declared itself virtual
A<D>* ptr = new E;
ptr->func(); // Calls D::func statically as D did not declare itself virtual
std::cin.get();

return 0;
}

visual studio 2010\projects\temp\temp\main.cpp(8): error C2352: 'B::func' : illegal call of non-static member function
visual studio 2010\projects\temp\temp\main.cpp(15) : see declaration of 'B::func'
visual studio 2010\projects\temp\temp\main.cpp(7) : while compiling class template member function 'void A<T>::func(void)'
with
[
T=B
]
visual studio 2010\projects\temp\temp\main.cpp(13) : see reference to class template instantiation 'A<T>' being compiled
with
[
T=B
]

最佳答案

我不确定我是否理解您的问题,但您似乎缺少必要的 CRTP 转换:

template<class T>
struct A {
void func() {
T& self = *static_cast<T*>(this); // CRTP cast
self.func();
}
};

struct V : A<V> { // B for the case of virtual func
virtual void func() {
std::cout << "V::func\n";
}
};

struct NV : A<NV> { // B for the case of non-virtual func
void func() {
std::cout << "NV::func\n";
}
};

如果 T 没有声明它自己的函数,这将是无限递归,因为 self.func 会找到 A ::func。即使 T 的派生类(例如下面的 DV)声明了它自己的 func 但 T 没有声明,也是如此。

使用不同的最终覆盖器进行测试,以显示广告中的调度工作:

struct DV : V {
virtual void func() {
std::cout << "DV::func\n";
}
};
struct DNV : NV {
void func() {
std::cout << "DNV::func\n";
}
};

template<class B>
void call(A<B>& a) {
a.func(); // always calls A<T>::func
}

int main() {
DV dv;
call(dv); // uses virtual dispatch, finds DV::func
DNV dnv;
call(dnv); // no virtual dispatch, finds NV::func

return 0;
}

关于c++ - 虚拟继承和静态继承——C++中的混合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4221163/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com