关于c ++:我得到错误:无法将变量’a’声明为抽象类型’A’

I get the error: cannot declare variable ‘a’ to be of abstract type ‘A’

这是我的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
#include <iostream>

using namespace std;

class Base
{
    public:
        virtual void Sub1() = 0;
        virtual void Sub2();
        virtual void Sub3();
        void Sub4();
};

class A : public Base
{
    public:
        void Sub2();
        void Sub4();
};

class B : public A
{
    public:
        virtual void Sub1();
        void Sub2();
};

class C : public Base
{
    public:
        virtual void Sub1();
        virtual void Sub4();
};

void Base::Sub2()
{
    cout <<"Hello from Base::Sub2()" << endl;
}

void Base::Sub3()
{
    cout <<"Hello from Base::Sub3()" << endl;
    Sub1(); // DONT MISS THIS CALL IN YOUR ANSWER
}

void Base::Sub4()
{
    cout <<"Hello from Base::Sub4()" << endl;
}

void A::Sub2()
{
    cout <<"Hello from A:Sub2()" << endl;
}
void A::Sub4()
{
    cout <<"Hello from A:Sub4()" << endl;
}

void B::Sub1()
{
    cout <<"Hello from B:Sub1()" << endl;
}
void B::Sub2()
{
    cout <<"Hello from B:Sub2()" << endl;
}

void C::Sub1()
{
    cout <<"Hello from C:Sub1()" << endl;
}
void C::Sub4()
{
    cout <<"Hello from C:Sub4()" << endl; //error used to say from Sub2
}

void Sub(Base& x)
{
    x.Sub1();
    x.Sub2();
    x.Sub3();
}
void AnotherSub(A& a)
{
    a.Sub1();
    a.Sub2();
    a.Sub4();
}

int main()
{
    A a; // wont compile
    B b;
    C c;
    Sub(a);
    Sub(b);
    Sub(c);
    AnotherSub(b);
}

我在A a;Sub(a);的末尾遇到了麻烦,因为a不能使用,但在最后,它说:"错误:不能将变量‘a’声明为抽象类型‘a’",任何帮助都会得到感激,谢谢。

---如果有帮助,没有a;的输出工作,看起来像:

1
2
3
4
5
6
7
8
9
10
11
    Hello from B:Sub1()
    Hello from B:Sub2()
    Hello from Base::Sub3()
    Hello from B:Sub1()
    Hello from C:Sub1()
    Hello from Base::Sub2()
    Hello from Base::Sub3()
    Hello from C:Sub1()
    Hello from B:Sub1()
    Hello from B:Sub2()
    Hello from A:Sub4()


这条线进入你的班级Base

1
virtual void Sub1() = 0;

如果不实现函数Sub1,则使类Base或扩展它的任何类成为抽象类,这就是类A的情况。

不能创建抽象类的实例,因为它有没有实现的方法,这意味着无法调用。这种类只能通过继承来使用。

因此,如果要创建A实例,则需要直接在BaseA上实现它。


我要添加的是,因为基是抽象的,类A不实现它的纯虚函数之一,所以A也是抽象的。由于抽象类不能被实例化(只允许指针和引用),我们使用抽象类的指针(比如指向a的指针)来实例化从抽象类(在本例中是a或base)派生的类的对象。因此,您需要提供纯虚拟函数的实现,并且必须使用类似的指针

1
2
A *a;
a = new B(); // it would compile now

希望你明白我的意思。


编译器是正确的:不能创建抽象类型的变量。您的class Base是抽象的,因为它声明了一个纯虚拟方法,即一个没有任何实现的函数:

1
    virtual void Sub1() = 0;

派生自Baseclass A也是抽象的,因为它不提供方法的重写实现。

必须为所有声明的虚拟方法提供实现,以使类型可实例化。当您重写class B中的纯虚拟Sub1()时,可以创建类B(及其子类)的变量,但class A不能用作变量的实际类型。


您正在从A扩展基类,但没有在a中实现纯虚方法。因此,需要将A作为抽象类。它不能是一个具体的类。

为了忽略将a抽象化并将其用作具体类,只需override纯虚方法,并且定义它时不包含任何语句。现在您可以为A创建一个实例。