gpt4 book ai didi

c++ - 如果调用未覆盖的虚方法,如何强制编译器错误?

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:37:45 25 4
gpt4 key购买 nike

在用 C++ 编写模板基类时,这是一个关于样式和安全性的相当普遍的问题。不过,请耐心等待,最后有一个具体问题...

我有一个模板基类,当类型 T 是原始类型(int、float 等)时,它完全实现了所需的功能。但是,如果 T 不是原始类型(例如,如果 T 是一个需要使用一组特定参数调用构造函数的类),则需要重写某些方法,因此它们在模板。该模板还包含一个纯虚方法,强制它是抽象的,因此为了使用它,必须派生自:基于原始类型的派生类可以使用提供的所有方法,并且仅重写纯虚方法,而基于非原始类型的派生类应重写所有虚方法。

例如:

template <typename T> class myTemplate
{
public:
// Constructor:
myTemplate<T>();

// Destructor:
virtual ~myTemplate();

// General function, valid for all classes derived from this:
void printMe()
{
printf("Hello, I'm from the template\r\n");
}

// Primitive function, must be overridden for non-primitive types:
virtual T DoSomething(const T& myClass)
{
T result = result + static_cast<T>(1);
return result;
}

// Primitive function, must be overridden for non-primitive types:
virtual T DoSomethingElse(const T& myClass)
{
T result = result - static_cast<T>(1);
return result;
}

// Pure Virtual function, must be overridden in all cases:
virtual void RefrainFromDoingAnythingAtAll(const T& myClass) = 0
};


class myIntegerClass : public myTemplate<int>
{
public:
virtual void RefrainFromDoingAnythingAtAll(const int& myInteger) {}
};

假设现在我想创建一个派生类,我希望在其中调用“DoSomething”,但无法设想“DoSomethingElse”在任何情况下都会有用。因此,我想重新实现“DoSomething”,而不是“DoSomethingElse”。然而,如果在某个时候派生类的“DoSomethingElse”方法确实被调用(或者因为我真的想调用“DoSomething”但是错误地写错了东西,或者因为出现了我遇到的情况早些时候未能设想),然后我希望发出编译器警告以提醒我我不能这样做,除非我先重新实现“DoSomethingElse”。

例如:

class myWatermelonClass : public myTemplate<Watermelon>
{
public:
virtual Watermelon DoSomething(const Watermelon &myWatermelon)
{
// Just return a copy of the original:
Watermelon anotherWatermelon(myWatermelon);
return anotherWatermelon;
}

virtual Watermelon DoSomethingElse(const Watermelon &myWatermelon)
{
// This routine shouldn't ever get called: if it does, then
// either I've made an error or, if I find that I really need
// to reimplement it after all, then I'd better buckle down
// and do it.
< How do I make the compiler remind me of this? >
}

virtual void RefrainFromDoingAnythingAtAll(const Watermelon& myWatermelon) {}
};

显然我知道标准的#error 和#warning 编译器指令,但如果我使用其中之一,那么每次编译时都会标记错误(或警告)。我想要的是如果我疏忽地调用,确保在编译时给出错误

DoSomethingElse(aSpecificWatermelon);

来 self 代码中的某处,但不是其他。有没有办法做到这一点?或者这从一开始就是一个糟糕的设计?

最佳答案

我认为您滥用了模板和虚拟调度组合。例如,您的基类不会针对任何不支持加法运算符且可从 int 构造的类型进行编译。每次myTemplate得到隐式特化,所有虚函数都会被编译,即使你在派生类中覆盖它们:

virtual T DoSomething(const T& myClass)
{
T result = result + static_cast<T>(1); // compile error when T == Watermelon
return result;
}

在你的情况下,你正在寻找的是显式模板特化:

template <>
class myTemplate<Watermelon>
{
public:
// General function, valid for all classes derived from this:
void printMe()
{
printf("Hello, I'm from the Watermelon template specialisation\r\n");
}

virtual Watermelon DoSomething(const Watermelon &myWatermelon)
{
// Just return a copy of the original:
Watermelon anotherWatermelon(myWatermelon);
return anotherWatermelon;
}

// notice there's no DoSomethingElse!

virtual void RefrainFromDoingAnythingAtAll(const Watermelon& myWatermelon) {}
};

现在打电话 DoSomethingElsemyTemplate<Watermelon> 的实例上会立即给你一个编译错误,因为没有这样的功能。

关于c++ - 如果调用未覆盖的虚方法,如何强制编译器错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24606668/

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