我理解为什么从构造函数调用虚函数是坏的,但我不确定为什么定义析构函数会导致"纯虚方法调用"异常.代码使用const值来减少动态分配的使用 - 可能也是罪魁祸首.
#include <iostream>
using namespace std;
class ActionBase {
public:
~ActionBase() { } // Comment out and works as expected
virtual void invoke() const = 0;
};
template <class T>
class Action : public ActionBase {
public:
Action( T& target, void (T::*action)())
: _target( target ), _action( action ) { }
virtual void invoke() const {
if (_action) (_target.*_action)();
}
T& _target;
void (T::*_action)();
};
class View {
public:
void foo() { cout << "here" << endl; } …Run Code Online (Sandbox Code Playgroud) 我有一个奇怪的问题,没有从DLL导出纯虚函数.DLL编译并输出.dll文件到目录.但它不会产生.lib文件.
如果我给出定义并且它不再将remian视为纯虚拟,那么在愉快之后它会创建.lib文件.
我需要实现工厂模式,我需要分离接口和实现.我的工厂实现和其他使用想要的.dll(任何.lib文件不生成)的接口需要使用该导出的函数,当我使用这些函数时,它们会产生链接错误......
例如"错误LNK2011:未解析的外部符号"public:......."
有任何想法如何导出纯虚函数,以便它们可以为其他exe和dll实现
关心乌斯曼
根据我对C++规范的了解(有限),具有虚拟成员的类的vtable被放置在第一个非纯非内联虚拟方法的定义中.编译器如何处理从具有ALL纯虚方法(例如接口)的类继承的类?在这种情况下,vtable放在哪里?
考虑以下 :
class Abstract
{
public:
virtual void func() = 0;
};
int main() {
Abstract abs1; // doesn't compile
Abstract * abs2 = new Abstract(); // doesn't compile
Abstract * abs3; // compiles
return 0;
}
Run Code Online (Sandbox Code Playgroud)
请注意我没有实现func(),那么为什么Abstract * abs3;
我们有一个纯虚方法和一个抽象类呢?我知道如果我尝试做abs3-> func(),我会遇到运行时错误.但是,我还不清楚为什么C++允许代码编译......?
谢谢,罗恩
我有一个纯粹的虚拟类定义如下:
class BaseClass {
protected:
const int var;
public:
void somefun() = 0; // what I mean by a purely virtual class
// stuff...
};
Run Code Online (Sandbox Code Playgroud)
如果我不添加如此定义的构造函数:
BaseClass(const int & VAR) : var(VAR) {};
Run Code Online (Sandbox Code Playgroud)
我必须在随后的派生类中使用,我的派生类不能将const变量var初始化为它想要的任何值.现在我真的明白这里发生了什么.在构造派生类之前,会调用基类的构造函数,此时必须初始化const成员变量.我的问题不是"如何使我的代码工作"这样的问题,这已经完成了.我的问题是为什么编译器认为这是必要的.对于纯粹的虚拟课程,我不应该被允许写下这样的内容:
class DerivedClass : BaseClass {
public:
DerivedClass() : var(SOME_VALUE) {};
}
Run Code Online (Sandbox Code Playgroud)
如果编译器知道对BaseClass构造函数的调用必然会跟随对某个派生类构造函数的调用(因为抽象类型的对象永远不能被实例化),它不应该给我们更多的回旋余地吗?
这是否是C++选择解决Diamond问题的结果?即使是这种情况,编译器是否应该至少以某种方式允许在派生类中定义纯虚函数的const成员变量的可能性?这太复杂了还是钻石问题的C++解决方案搞得一团糟?
感谢大家的帮助.
可能重复:
在构造函数内调用虚函数
看看这段代码.在Base类的构造函数中,我们可以使用'this'指针调用纯虚函数.现在,当我想创建一个指向同一个类的类型指针并将"this"转换为相同类型时.它抛出运行时异常'纯虚函数调用异常'.为什么会这样?
#include <iostream>
using namespace std;
class Base
{
private:
virtual void foo() = 0;
public:
Base()
{
//Uncomment below 2 lines and it doesn't work (run time exception)
//Base * bptr = (Base*)this;
//bptr->foo();
//This call works
this->foo();
}
};
void
Base::foo()
{
cout << "Base::foo()=0" << endl;
}
class Der : public Base
{
public:
Der()
{
}
public:
void foo()
{
cout << "Der::foo()" << endl;
}
};
int main()
{
cout << "Hello World!" …Run Code Online (Sandbox Code Playgroud) 给出以下代码示例,为什么重载AbstractBaseClass::DoAThing( const char* )不可见作为SomeEndClass实现重载纯抽象DoAThing( const char* const* )方法的继承方法?
class AbstractBaseClass
{
public:
virtual void DoAThing( const char* withThis ) {}
virtual void DoAThing( const char* const* withThat ) = 0;
AbstractBaseClass() {}
virtual ~AbstractBaseClass() {}
};
class SomeMiddlewareClass : public AbstractBaseClass
{
public:
void ThisIsCool() {}
SomeMiddlewareClass() {}
virtual ~SomeMiddlewareClass() {}
};
class SomeEndClass : public SomeMiddlewareClass
{
public:
void DoAThing( const char* const* withThat ) {}
SomeEndClass() {}
virtual ~SomeEndClass() {}
};
void …Run Code Online (Sandbox Code Playgroud) 我有一个类A,它有一个指向纯虚拟类的实例的指针B.类C派生自B并将自动具有指向A(其父级)的指针,并且需要访问其成员.这可以通过添加friend class C内部类来实现A,尽管这对于将派生的每个类都是必需的B.
代码示例:
class A
{
public:
friend class B; // This does not allow derived classes to be friends
friend class C; // Now derived class B has access to `DoDomething`, but then this is needed for every single derived class
private:
void DoDomething();
};
class B
{
virtual void Tick() = 0;
protected:
A* m_pointerToA; // <- is being set upon …Run Code Online (Sandbox Code Playgroud) 我是一名学习C ++的学生。我正在为我的程序创建一个涉及继承和抽象/具体类的UML类图,但是我不太确定如何表示纯虚函数。任何帮助表示赞赏,谢谢!
我有一个适配器类,它处理相同概念的类。
现在,我希望该适配器基于模板参数RO(只读)来禁用pack(). 但我不知道纯虚拟是否不支持这一点,或者只是我写错了。
template<bool RO> // means read only functionality
class Adapter
{
struct AbstractAdapter
{
virtual ~AbstractAdapter() = default;
virtual void unpack() = 0;
virtual void pack() = 0 requires (!RO); // compile ERROR!! ERROR!! ERROR!!
};
template<typename T> requires (Reader<T> || Writer<T>)
struct TemplateAdapter : public AbstractAdapter
{
virtual void unpack()
{
if constexpr (!Reader<T>) throw UnsupportedOperationEx{};
else client.unpack();
}
virtual void pack() requires (!RO)
{
if constexpr (!Writer<T>) throw UnsupportedOperationEx{};
else client.pack();
} …Run Code Online (Sandbox Code Playgroud) c++ ×10
pure-virtual ×10
c++-concepts ×1
const ×1
friend ×1
function ×1
inheritance ×1
interface ×1
methods ×1
polymorphism ×1
uml ×1
vtable ×1