gpt4 book ai didi

c++ - 避免无休止的虚拟查找

转载 作者:行者123 更新时间:2023-11-30 05:39:45 25 4
gpt4 key购买 nike

考虑这段代码:

#include <iostream>
#include <string>

class Base {
protected:
virtual std::string addMoreDetail (std::string&) const = 0;
};

template <int...> class Derived;

template <>
class Derived<0, 0> : private Base {
private:
bool b;
protected:
virtual std::string description() const {return "Whatever1";}
std::string finalize (std::string& str) const {return b ? addMoreDetail(str) : str;}
};

template <>
class Derived<1, 0> : private Base {
protected:
virtual std::string description() const {return "Whatever2";}
std::string finalize (std::string& str) const {return addMoreDetail(str);}
};

template <int N>
class Derived<N, 0, 0> : public Derived<N, 0> {
public:
virtual std::string description() const override {
std::string str = Derived<N, 0>::description(); return this->finalize(str);
// Can this be moved up somehow?
}
private:
inline std::string addMoreDetail (std::string& s) const {return s + " Detail1";}
};

template <int N>
class Derived<N, 0, 1> : public Derived<N, 0> {
public:
virtual std::string description() const override {
std::string str = Derived<N, 0>::description(); return this->finalize(str);
// Can this be moved up somehow?
}
private:
inline std::string addMoreDetail (std::string& s) const {return s + " Detail2";}
};

int main() {
std::cout << Derived<0, 0, 0>().description() << '\n'; // Whatever1
std::cout << Derived<0, 0, 1>().description() << '\n'; // Whatever1
std::cout << Derived<1, 0, 0>().description() << '\n'; // Whatever2 Detail1
std::cout << Derived<1, 0, 1>().description() << '\n'; // Whatever2 Detail2
}

我的目标很简单。我想避免写作

std::string str = Derived<N, 0>::description();   return this->finalize(str);

通过在层次结构中将其向上移动两次。

这是我的临时解决方案:

#include <iostream>
#include <string>

template <int...> class Derived;

class Base {
protected:
virtual std::string description() const = 0;
virtual std::string addMoreDetail (std::string&) const = 0;
template <int N> std::string descriptionBase (const Derived<N, 0>* derived) const {
// std::string str = derived->description(); return derived->finalize(str); // Endless look-up!
std::string str = derived->staticDescription(); return derived->finalize(str);
}
};

template <>
class Derived<0, 0> : protected Base {
private:
bool b;
friend Base;
protected:
virtual std::string description() const {return staticDescription();}
static std::string staticDescription() {return "Whatever1";}
std::string finalize (std::string& str) const {return b ? addMoreDetail(str) : str;}
};

template <>
class Derived<1, 0> : protected Base {
friend Base;
protected:
virtual std::string description() const {return staticDescription();}
static std::string staticDescription() {return "Whatever2";}
std::string finalize (std::string& str) const {return addMoreDetail(str);}
};

template <int N>
class Derived<N, 0, 0> : public Derived<N, 0> {
public:
std::string description() const override {return this->template descriptionBase<N>(this);}
private:
inline std::string addMoreDetail (std::string& s) const {return s + " Detail1";}
};

template <int N>
class Derived<N, 0, 1> : public Derived<N, 0> {
public:
std::string description() const override {return this->template descriptionBase<N>(this);}
private:
inline std::string addMoreDetail (std::string& s) const {return s + " Detail2";}
};

int main() {
std::cout << Derived<0, 0, 0>().description() << '\n'; // Whatever1
std::cout << Derived<0, 0, 1>().description() << '\n'; // Whatever1
std::cout << Derived<1, 0, 0>().description() << '\n'; // Whatever2 Detail1
std::cout << Derived<1, 0, 1>().description() << '\n'; // Whatever2 Detail2
}

但这在我的程序中实际上不起作用,因为 description() 不是静态的,因为它依赖于数据成员。然而,如果我使用

std::string str = derived->description();   return derived->finalize(str);

代替

std::string str = derived->staticDescription();   return derived->finalize(str);

我得到了一个运行时无休止的虚拟查找,因为它不断地回到原来的位置。如何避免这种情况?还是有更好的方法来实现我的目标?

最佳答案

使您的 staticDescription 方法成为非虚非静态成员函数,即在定义 staticDescription 时保持代码不变并删除 static > 方法。也许您想将 staticDescription 重命名为 doGetDescription 左右。

通常的解决方案可能是使用模板方法模式(或非虚拟接口(interface)模式):

class BaseClass {
public:
std::string getDescription () const {
return this->doGetDescription ();
}

private:
virtual std::string doGetDescription () const = 0;
};

class FirstDerived : public BaseClass {
std::string doGetDescription () const override { return "First"; }
};

class SecondDerived : public BaseClass {
std::string doGetDescription () const override { return "Second"; }
};

BaseClass & b = SecondDerived {};
std::cout << b.getDescription () << std::endl;

关于c++ - 避免无休止的虚拟查找,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32153270/

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