我们可以在C ++类中编写abstract关键字吗?
答案 0 :(得分:42)
#define abstract
答案 1 :(得分:38)
没有
C ++中的纯虚函数声明为:
class X
{
public:
virtual void foo() = 0;
};
任何至少有一个类的类都被认为是抽象的。
答案 2 :(得分:18)
不,C ++没有关键字摘要。但是,你可以写pure virtual functions;这是表达抽象类的C ++方式。
答案 3 :(得分:5)
这是一个关键字,作为.NET框架的C ++ / CLI语言的一部分而引入。
答案 4 :(得分:3)
不,你需要在一个类中至少有一个纯虚函数是抽象的。
这是一个很好的参考cplusplus.com
答案 5 :(得分:2)
正如其他人所指出的,如果你添加一个纯虚函数,那么这个类就变成了抽象的。
但是,如果要实现没有纯虚拟成员的抽象基类,我发现使构造函数受到保护很有用。这样,您强制用户将ABC子类化以使用它。
示例:
class Base
{
protected:
Base()
{
}
public:
void foo()
{
}
void bar()
{
}
};
class Child : public Base
{
public:
Child()
{
}
};
答案 6 :(得分:1)
不,您不能将abstract用作关键字,因为C ++中没有这样的关键字。
如果你想在C ++抽象中创建一个类,你可以将至少一个函数声明为纯虚函数。
但是在派生类中,你必须提供定义,否则它会给出编译错误。
示例:
class A
{
public:
virtual void sum () = 0;
};
注意:强>
你可以使用abstract作为变量名,类名,因为正如我所说,abstract不是C ++中的关键字。
答案 7 :(得分:0)
没有关键字' abstract'但是一个纯虚函数将一个类转换为抽象类,可以将其扩展并重新用作接口。
答案 8 :(得分:0)
不,C ++没有关键字摘要。但是,您可以编写纯虚函数;这是C ++表达抽象类的方式。它是作为.NET框架的C ++ / CLI语言的一部分引入的关键字。您需要在类中至少有一个纯虚函数是抽象的。
class SomeClass {
public:
virtual void pure_virtual() = 0; // a pure virtual function
};
答案 9 :(得分:0)
大多数 C++ 编译器没有 abstract
关键字。
尽管您可以像这样定义一个具有该名称的宏:
#define abstract
class foo abstract { ... };
它对类绝对没有影响,但是,如果任何变量、函数或任何东西都被命名为“抽象”,那么 #define
不会让你的代码快乐。
正如其他人所提到的,您可以通过创建一个纯虚函数并将其设置为 0
来强制一个类为抽象类:
class foo
{
virtual void func() = 0;
};
foo::func() { /* some default code [not required] */ }
优点: 由于即使是纯虚函数也可以有主体,因此即使定义为抽象(纯虚)的函数已被定义,您也可以使类抽象。但是,与其他虚函数相反,纯虚函数不需要具有主体。
缺点:您被迫创建至少一个纯虚函数,并强制所有派生类定义该函数不被视为抽象函数。如果你反正有这样的功能,那就太好了!但通常情况并非如此。
实际上有一种巧妙的方法可以创建一个鲜为人知的抽象类。你仍然需要创建一个纯虚函数……事实上,析构函数可以是一个纯虚函数!在使用 virtual
关键字的类中总是有一个析构函数,所以这里没有任何犹豫。
class foo {
virtual ~foo() = 0;
};
foo * f(new foo); // this fails, foo is abstract
从 foo 派生的类现在必须声明一个显式析构函数(较新的编译器正确地隐式创建了一个,但它仍然是一个纯虚函数),它不是像这样的纯虚:
class bar : public foo {
virtual ~bar() override {}
};
请注意,我们没有 abstract
关键字,但我们有一个 override
关键字,这非常有用,因此当函数签名更改时,您无法编译,直到所有派生自的类您的基类的虚函数会相应更新。
使用析构函数作为纯虚函数的一个有趣的方面是派生类会自动获得一个析构函数(如果你没有定义),这意味着你的派生类自动是非抽象的(假设只有析构函数是纯的基类中的虚拟)。
换句话说,您可以声明 bar
:
class bar : public foo {
void some_function();
};
并且它自动不是抽象的,因为默认的析构函数不是抽象的,因为它或多或少看起来像这样:
virtual ~bar() override {}
如果你不自己定义。
换句话说,如果你想定义另一个仍然是抽象的层(即如果你想让 new bar
编译失败),那么你必须声明你自己的析构函数并将其标记为纯虚拟:< /p>
class bar : public foo {
virtual ~bar() override = 0;
void some_function();
};
bar::~bar() {}
({}
和 = 0
不能一起使用,因此您必须单独声明析构函数体。)