在超类中调用抽象方法,并在C++中的子类中实现它
Invoke abstract method in super class, and implement it in subclass in C++?
在Java中,可以用未实现的抽象方法和调用抽象方法的非抽象方法编写一个抽象的超类。然后在子类中是实现的抽象方法。当您创建子类的实例时,超级类使用子类中的实现。我如何在C++中实现这一点?
这是我的意思,但在Java中:
SuperClass.java
public abstract class SuperClass {
public SuperClass() {
method();
}
private void method() {
unimplementedMethod();
}
protected abstract void unimplementedMethod();
}
SubClass.java
public class SubClass extends SuperClass {
public SubClass() {
super();
}
@Override
protected void unimplementedMethod() {
System.out.println("print");
}
public static void main(String[] args) {
new SubClass();
}
}
如果你向我展示如何在C++中实现这一点,那将是非常棒的。:)
通常,您要查找的是virtual
关键字。简而言之,virtual
声明了此方法可以被覆盖的意图。注意,这样的方法仍然可以有一个实现——virtual
只是使它可以被覆盖。要声明一个"抽象方法",可以说declare intent ofplease provide a implementation in the derived classwith = 0
,如下所示。这样的方法在C++中被称为纯虚拟。
然而,有一些注意事项需要注意。正如下面的注释所指出的,您是从SuperClass
构造函数中调用method()
的。不幸的是,由于对象的构造顺序,这在C++中是不可能的。
在C++中,派生类构造函数在分配其成员或执行构造函数主体之前立即调用其超类构造函数。因此,基类的成员首先构造,派生类的成员最后构造。从基类调用虚拟方法在Java中不会像您预期的那样工作,因为派生类尚未构造,因此虚拟方法尚未重定向到派生实现。希望这是有道理的。
然而,在创建后对SuperClass
对象调用method()
将如您所期望的那样工作:它将调用将输出"print"的虚拟函数。
class SuperClass {
public:
SuperClass() {
// cannot call virtual functions from base constructor.
}
virtual ~SuperClass() { } // destructor. as Kerrek mentions,
// classes that will be inherited from,
// should always have virtual destructors.
// This allows the destructors of derived classes
// to be called when the base is destroyed.
private:
void method() {
unimplementedMethod();
}
protected:
virtual void unimplementedMethod() = 0; // makes method pure virtual,
// to be implemented in subclass
}
h子类
class SubClass : public SuperClass {
public:
SubClass() : SuperClass() { // how the superclass constructor is called.
}
// no need for "override" keyword, if the methd has the same name, it will
// automatically override that method from the superclass
protected:
void unimplementedMethod() {
std::cout << "print" << std::endl;
}
}
在C++中,您永远不应该在构造函数中调用虚拟函数,因此它不能像字面上那样工作。最好使用单独的成员功能
class SuperClass
{
public:
void action() { method(); } // not in the constructor, please
virtual ~SuperClass() { } // always a virtual destructor when polymorphic
protected:
void method() { unimplementedMethod(); }
private:
virtual void unimplementedMethod() = 0;
};
class SubClass : public SuperClass
{
private:
virtual void unimplementedMethod() { std::cout << "print" << std::endl; }
// no need to spell out the next couple of functions, but for your entertainment only
public:
SubClass() : SuperClass() { }
virtual ~SubClass() { }
};
现在调用:
int main()
{
SuperClass * p = new SubClass; // construct first...
p->action(); // ... then invoke, after construction is complete
delete p; // thank god for that virtual destructor!
}
基构造函数在构造派生类之前运行,因此不能在基构造函数中调用任何派生函数,特别是不能调用任何纯虚拟函数。
请注意,private
和protected
的方式不对:非虚拟访问器函数应该是protected
,这样它就可以在整个类层次结构中使用,但虚拟实现函数应该是private
,因为它只需要由同一类中的访问器函数看到。简而言之:受保护的非虚拟和私人虚拟。
(这个用法示例有点做作,因为您通常不会在C++中使用new
或原始指针。)
在C++中,这些被称为纯虚拟函数/方法。
基本上,你在一个方法的末尾加上一个"=0":
virtual doSomething() = 0; // pure virtual
在SO周围搜索"c++纯虚拟",你会发现大量的答案。
您需要使用虚拟方法。实现方式如下:
/* here's MyBaseClass.h */
class MyBaseClass
{
public:
MyBaseClass(void);
~MyBaseClass(void);
void MyMethod();
protected:
virtual void MyUnimplementedMethod() = 0;
};
/* here's MyIneritedClass.h */
class MyInheritedClass :
public MyBaseClass
{
public:
MyInheritedClass(void);
~MyInheritedClass(void);
protected:
virtual void MyUnimplementedMethod();
};
/* here's the implementation of the method in the base class */
void MyBaseClass::MyMethod()
{
MyUnimplementedMethod();
}
/* and here's the implementation of the abstract method in the derived */
void MyInheritedClass::MyUnimplementedMethod()
{
_tprintf(L"Hello, world");
}
您将方法声明为virtual
:
代码段:
class Parent{
public:
virtual int methodA() {return methodB();}; // calls the abstract method
virtual int methodB() = 0; // "=0" means pure virtual, not implemented in the base
}
class Child : public Parent{
public:
virtual int methodB() { /* implementation */}
}
virtual
意味着子级可以覆盖实现,而父级则应该调用覆盖实现。在virtual
方法的声明中添加"=0"使其纯虚拟,即:基没有自己的实现,而是依赖于子级的实现。这样的类不能实例化(即:抽象类)。
- C ++类型特征:确保子类实现方法
- 将C++子类成员函数(虚拟实现)传递给 C 类型函数指针
- C++强制在子类中实现方法,但具有不同的签名
- 无法使用在子类中定义的虚拟getter实现基类
- C++接口实现和子类化对象识别
- 如何在子类中重写时调用私有虚拟基类实现
- 如何在基类中实现子类迭代器的统一接口?
- C :在f的派生类实现中,可以用x的子类型代替纯虚拟函数f的参数x
- 有没有办法在不重新实现的情况下从子类中标记父级的虚拟函数 final。
- 如何以相同的方法在子类中超载的相同方法来实现工作变量参数方法
- C++父类,在2个不同的子类中实现了虚拟方法
- 在子类之外实现函数导致未知错误
- 在子类中实现继承类的方法(param=指向父级的指针)(param=指向子级的指针)
- 编写子类构造函数的实现
- 强制子类在C++中实现某个构造函数原型
- 强制子类实现并调用(一次)方法
- 如何实现子类的构造函数?
- 在超类中调用抽象方法,并在C++中的子类中实现它
- 抽象类方法用其他基类的子类实现
- 获取 QWidget 的 Windows 消息而不对其进行子类化并重新实现 QWidget::winEvent