我可以理解,可能有理由声明一个已实现(而不是纯粹)的私有或受保护的虚拟函数.Afaik,如果您将已实现的虚拟方法声明为受保护,则您的子类可以调用基类的方法(并且没有其他人可以).如果将其声明为private,则只有基类可以调用virtual方法的默认实现.
但是,对于纯虚拟机,没有基本实现......那么在功能上是否等同于将纯虚拟声明为私有或受保护?受保护的纯虚拟没有意义,因为您无法调用基类的相应方法.是否存在受保护的纯虚拟有意义的情况?
SO上有一些类似的主题,但我找不到任何简洁回答我问题的内容.
我明白为什么会发生这种情况,但我一直试图解决它...这是我的代码在我的程序退出时生成错误(因此导致崩溃)时所做的事情...
pure virtual method called
SomeClass::~SomeClass()
{
BaseClassObject->SomePureVirtualMethod(this);
}
Run Code Online (Sandbox Code Playgroud)
void DerivedClass::SomePureVirtualMethod(SomeClass* obj)
{
//Do stuff to remove obj from a collection
}
Run Code Online (Sandbox Code Playgroud)
我从来没有打过电话,new SomeClass但我有一个QList<SomeClass*>我追加SomeClass*对象的东西.这个析构函数的目的SomeClass是告诉从它的集合中DerivedClass删除一个特定的实例.SomeClassQList<SomeClass*>
所以,在一个具体的例子......
BaseClass = Shape
DerivedClass = Triangle
SomeClass= ShapeProperties拥有对的引用Shape
所以,我从来没有打过电话,new ShapeProperties但我有一个QList<ShapeProperties*>内心Triangle.析构函数ShapeProperties是告诉从它的集合中Triangle删除特定属性.ShapePropertiesQList<ShapeProperties*>
class Foo
{
public:
virtual int foo() final = 0;
};
Run Code Online (Sandbox Code Playgroud)
编译好.
这不Foo只是浪费空间,而是制造事故吗?或者我错过了什么?
注意:我不问这样做是否合理,或者这是否是好的设计。我只是问这是否是明确定义的行为,以及结果是否符合预期。
我遇到了以下类层次结构:
struct A
{
virtual void foo() = 0;
};
struct B: public A
{
void foo() override
{
std::cout << "B::foo()\n";
}
};
struct C: public B
{
virtual void foo() = 0;
};
struct D: public C
{
void foo() override
{
std::cout << "D::foo()\n";
}
};
int main()
{
A* d = new D;
d->foo(); //outputs "D::foo()"
// A* c = new C; // doesn't compile as expected
}
Run Code Online (Sandbox Code Playgroud)
这段代码定义得好吗?我们是否允许使用纯说明符覆盖定义?
C++标准规定禁止从构造函数或析构函数中调用纯虚函数.这是什么原因?标准为什么要设置这样的限制?
从10.4 抽象类 parag.标准中的6:
"可以从抽象类的构造函数(或析构函数)调用成员函数;直接或间接地对从这样的构造函数(或析构函数)创建(或销毁)的对象进行纯虚函数的虚拟调用的效果未定义."
假设标准允许从构造函数(或析构函数)调用非纯虚函数,为什么区别?
[编辑]关于纯虚函数的更多标准引用:
§10.4/ 2通过在类定义中的函数声明中使用纯说明符(9.2)来指定虚函数.只有在使用(12.4)qualified-id语法(5.1)调用时,才需要定义纯虚函数.... [注意:函数声明不能同时提供纯指定符和定义-end note]
§12.4/ 9 析构函数可以声明为虚拟(10.3)或纯虚拟(10.4); 如果在程序中创建了该类或任何派生类的任何对象,则应定义析构函数.
一些需要回答的问题是:
如果纯虚函数没有给出实现,那么这不应该是编译器或链接器错误吗?
在为纯虚函数赋予实现的情况下,为什么在这种情况下不能很好地定义它来调用这个函数?
用另一个纯虚方法覆盖纯虚方法是否有意义?是否有任何功能差异或代码风格的原因,而不是选择以下选项之一?
class Interface {
public:
virtual int method() = 0;
};
class Abstract : public Interface {
public:
int method() override = 0;
};
class Implementation : public Abstract {
public:
int method() override { return 42; }
};
Run Code Online (Sandbox Code Playgroud)
与:
class Interface {
public:
virtual int method() = 0;
};
class Abstract : public Interface {};
class Implementation : public Abstract {
public:
int method() override { return 42; }
};
Run Code Online (Sandbox Code Playgroud) 我有一个基类
class ShapeF
{
public:
ShapeF();
virtual ~ShapeF();
inline void SetPosition(const Vector2& inPosition) { mPosition.Set(inPosition); }
protected:
Vector2 mPosition;
}
Run Code Online (Sandbox Code Playgroud)
显然有一些遗漏的代码,但你明白了.我使用它作为模板,并使用一些有趣(ommited)枚举,一种方法来确定我正在使用什么样的形状
class RotatedRectangleF : public ShapeF
{
public:
RotatedRectangleF();
virtual ~RotatedRectangleF();
protected:
float mWidth;
float mHeight;
float mRotation;
}
Run Code Online (Sandbox Code Playgroud)
ShapeF通过定位和定义类型的枚举来完成它的工作.它有访问器和mutator,但没有方法.
我可以将ShapeF设为抽象类,以确保没有人尝试并实例化ShapeF类型的对象吗?
通常,这可以通过在ShapeF中使用纯虚函数来实现
//ShapeF.h
virtual void Collides(const ShapeF& inShape) = 0;
Run Code Online (Sandbox Code Playgroud)
但是,我目前正处理一个单独的类中的冲突.我可以移动所有东西,但我想知道是否有一种方法可以使类抽象...没有纯虚函数.
假设我有以下代码:
class Iinterface
{
virtual void abstractFunction()=0;
};
class Derived : public Iinterface
{
void abstractFunction(); // Do I need this line?
};
Derived::abstractFunction()
{
// implementation here
}
Run Code Online (Sandbox Code Playgroud)
如果我没有添加有问题的行,我会收到编译错误,说明abstractFunction未声明Derived.我正在使用VS 2008.
我不确定为什么我需要这个特定的行(不要把它与类声明之外提供的函数定义混淆),只要我继承Iinterface它就应该很明显我abstractFunction声明了.这是Visual Studio的问题还是由c ++标准强制执行?
不是从构造函数调用虚函数和纯虚函数的重复:
前一个问题涉及C++ 03,而不是C++ 11中新的构造函数委派行为,并且该问题没有通过使用委托来确保在执行纯虚拟实现之前正确构造来解决未定义行为的问题.
在C++ 11中,在构造期间在类的构造函数中调用Pure Virtual函数有什么危险,但是在通过构造函数委托"完全构造"类/对象之后?
显然,在C++ 11规范的某个地方存在这样的约束,
可以为正在构造的对象调用成员函数(包括虚拟成员函数,10.3).类似地,正在构造的对象可以是typeid运算符的操作数. - [C++工作草案]的12.6.2#13(http://www.open-std.org/jtc1/sc22/wg21/docs/ papers/2011/n3242.pdf)找不到已发布规范的"合理使用"版本.
一旦任何构造函数完成执行,C++ 11就会考虑构造一个对象.由于将允许多个构造函数执行,这意味着每个委托构造函数将在其自己类型的完全构造的对象上执行.派生类构造函数将在其基类中的所有委托完成后执行.- 维基百科说这是C++ 11的事情.
实际C++ 11参考未知.
以下示例在Visual Studio 2012 C++编译器的Nov CTP中编译和运行RUNS:
#include <string>
/**************************************/
class Base
{
public:
int sum;
virtual int Do() = 0;
void Initialize()
{
Do();
}
Base()
{
}
};
/**************************************/
// Optionally declare class as "final" to avoid
// issues with further sub-derivations.
class Derived final : public Base
{
public:
virtual int Do() override final
{ …Run Code Online (Sandbox Code Playgroud) c++ ×10
pure-virtual ×10
polymorphism ×3
c++11 ×2
constructor ×2
overriding ×2
abstract ×1
base-class ×1
coding-style ×1
delegation ×1
destructor ×1
final ×1
inheritance ×1
interface ×1
standards ×1