我正在进行一项练习,要求我拿一个基类Rodent并使它成为一个纯粹的抽象类.我对纯抽象类的理解是它充当接口并且只包含纯虚函数.虽然这是一个简单的练习,但我对本书提供的解决方案有疑问:
class Rodent
{
public:
virtual ~Rodent() {cout << "Destroy rodent" << endl;}
virtual void run() = 0;
virtual void squeak() = 0;
};
Run Code Online (Sandbox Code Playgroud)
如您所见,作者为析构函数添加了一个虚拟定义.添加这个定义是否意味着这不是一个抽象类而不是一个"纯粹的"抽象类?
可能我只是从文档中错过了一些东西(或者只是不能做适当的Google搜索),但是我shared_ptr和纯虚拟函数都存在问题。
因此,一个简短的示例有效:
class Base
{
public:
virtual int stuff() = 0;
};
class Derived : public Base
{
public:
virtual int stuff() {return 6;}
};
class Container
{
public:
Container() : m_x( 0 ) {}
Container(Base* x) : m_x(x) {}
private:
Base* m_x;
};
Run Code Online (Sandbox Code Playgroud)
并且由于我想使用新的样式,因此将std::shared_ptr修改Container为:
class Container
{
public:
Container() : m_x( std::make_shared<Base>() ) {}
Container(const std::shared_ptr<Base>& x) : m_x(x) {}
private:
std::shared_ptr<Base> m_x;
};
Run Code Online (Sandbox Code Playgroud)
显然,这是不行的,铛和其他编译器抱怨,即:error: allocating an object of abstract class type …
为了验证语句" 编译器和链接器强制存在的纯虚拟析构函数的函数体. "这篇geeksforgeeks文章,我编译了这段代码:
class Base
{
public:
virtual ~Base()=0; // Pure virtual destructor
};
class Derived : public Base
{
public:
~Derived()
{
std::cout << "~Derived() is executed";
}
};
int main()
{
//Derived d; <<<
return 0;
}
Run Code Online (Sandbox Code Playgroud)
编译没有任何错误.那么为什么编译器在这种情况下没有选择强制执行函数体的存在呢?
在我的头文件中,我已经声明了 2 个公共成员文件是像这样的纯虚函数
头文件
class Whatever
{
public:
virtual bool Update() = 0;
virtual bool ShouldBeVisible() = 0;
};
Run Code Online (Sandbox Code Playgroud)
执行
bool Whatever::Update();
bool Whatever::ShouldBeVisible();
Run Code Online (Sandbox Code Playgroud)
但是,当我尝试编译,我把一个错误,指出:乱行成员的声明必须在一个定义的更新和ShouldBeVisible。当我在实现中去掉分号时,我得到一个不同的错误,上面写着“预期的”“;” 之后顶层声明符和成员外的网上申报必须是定义用于更新和之后函数声明预期的函数体为ShouldBeVisible。
答案可以在这里找到:
url发布者:hmjd
请阅读该页面,以便了解其发生的原因.你也知道为什么要替换
virtual void OnRelease() = 0;
Run Code Online (Sandbox Code Playgroud)
通过:
virtual void OnRelease(){};
Run Code Online (Sandbox Code Playgroud)
将起作用,但不是正确的解决方法.
原始问题
R6025:纯虚函数调用
#include <Windows.h>
// static lib
//file.h
class cBaseApplication
{
public:
virtual ~cBaseApplication(){ Release(); }
virtual void Release()
{
OnRelease();
};
virtual void OnRelease() = 0;
}; // class cBaseApplication
//file1.h
class cApplication : public cBaseApplication
{
public:
virtual void OnRelease()
{
/* what the heck do something here */
};
}; // class cApplication
// executable
// file3.h
int WINAPI …Run Code Online (Sandbox Code Playgroud) 例:
class IGui{
protected:
virtual bool OnClicked(){return false;}
virtual bool OnHover(){return false;}
virtual bool OnScrollBarChange(){return false;}
virtual bool OnTextChange(){return false;}
...
}
class IGuiButton: public IGui{
protected:
virtual bool OnClicked() = 0;
virtual bool OnHover(){
do stuff
return true;}
...
}
Run Code Online (Sandbox Code Playgroud)
关键是要为所有gui类型提供一个commom接口(不需要覆盖所有虚拟内容),然后为按钮提供lite特化,但是对于按钮,theres必须是OnClicked的覆盖..
此外,我认为我应该使那些按钮不应该覆盖私有(所以使用私有继承,并使用那个花哨的"使用Base :: Method;"来使特定的保护?
考虑遵循Java程序:
abstract class Surprising
{
void fun()
{
System.out.println("fun() is invoked");
}
}
class myclass
{
public static void main(String args[])
{
Surprising s=new Surprising() { };
s.fun();
}
}
Run Code Online (Sandbox Code Playgroud)
这里我创建了我的抽象类令人惊讶的无名子类的对象,而不是抽象类的对象,因为它不允许在Java中创建抽象类的对象.
什么是等效的C++程序?是否可以在C++中执行此操作?如果是,怎么回事,为什么不允许?
我创建了一个抽象类,它只有一组纯虚方法.有3个不同的类具有这些方法的具体实现.
在编写了上述结构之后,我发现派生类中的一些方法具有相同的实现.所以,我将这些函数转移到我的基类的逻辑,并使它们成为虚拟而不是纯虚拟.现在,实现不需要在派生类中重复.这编译并执行正常.
我的基类是纯虚方法和虚方法的混合,它遵循这样的结构是一种很好的设计方法吗?
尝试将关键字定义PURE为const集0,以用作抽象数据类型的类的标识符.为什么不编译?Per Meyers在"Essential C++,topic 1"中,我更喜欢使用const而不是#define,就像这样:
const int PURE = 0;
virtual void myFunction() = PURE;
Run Code Online (Sandbox Code Playgroud)
唉,这会引发错误(在Apple LLVM 7.0和gcc上也是如此):
Initializer on function does not look like pure-specifier
Run Code Online (Sandbox Code Playgroud)
下面是一个例子,标有A,B和C三种技术;
1. const int PURE = 0 will not compile
2. #define PURE 0 compiles and runs fine
3. Simply setting function = 0 (Stroustrup) works fine.
Run Code Online (Sandbox Code Playgroud)
它现在设置使用const解决方案,因此不会编译.简单地评论/取消注释第4,5,11和12行,以检查三种不同的方法:
#include <iostream>
#include <string>
const int PURE = 0; // Case B
// #define PURE 0 // Case C …Run Code Online (Sandbox Code Playgroud) 我在工作项目中发现了一些代码,当子类没有重写基类函数时,该代码会引发错误(实际上,使用此实用程序的基类实际上是抽象的)。当我看到此消息时,我的第一个反应是:“为什么他们不使这些方法成为纯虚拟方法?” 但是,有问题的代码已有15年的历史了,我不确定是否创建该代码是为了填补纯虚拟设备以后会填补的空白(假设当时不存在)。
如果自那时以来存在纯虚拟方法,是否有任何理由为其提供附加或替代功能?(我意识到这可能是主观的,但我什至没有起点)。
如果没有,是否有任何文献指出哪个标准引入了它们?
c++ abstract-class virtual-functions pure-virtual language-lawyer
c++ ×10
pure-virtual ×10
inheritance ×3
abstract ×1
c++11 ×1
class ×1
compilation ×1
destructor ×1
java ×1
shared-ptr ×1
visual-c++ ×1