编译器未检测到的抽象类 [英] abstract classes not detected by compiler

查看:67
本文介绍了编译器未检测到的抽象类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我通过使用纯虚拟

方法声明类来使用C ++中的接口。如果有人想要实现界面,他们需要从类中继承
。如果实现类忘记了
实现了一些方法,我通常会遇到编译错误(如果以某种方式创建类的话,那就是
)。然而,在使用Visual

Studio 6编译器时,它不会在这个

的情况下生成编译错误:


- I有一个继承自接口类的实现类A.它没有实现所有方法。

- 实现类A被声明为容器类中的数组。

容器类是用new创建的。


编译器不会产生任何错误,但我当然会得到一个运行时
$ b调用没有实现的方法时出现$ b错误(纯函数调用或

某事)。如果容器类将A声明为指针(并对其执行新的
)或作为非数组变量,则编译器会生成编译

错误,但如果它被声明为数组。


所以,我的问题是:它是编译器错误,如果它没有发现

抽象类是创建(这是这种情况,因为所有方法都没有实现
)?或者是否应该认为编译器不能正常#b $ b找出这样的情况(即更复杂的情况)。


/ Bjorn

解决方案

Bjorn写道:

我在C ++中使用接口来声明只有纯虚拟的类
方法。如果有人想要实现接口,他们需要从类中继承。如果实现类忘记实现某些方法,我通常会遇到编译错误(如果以某种方式创建类的话)。然而,在使用Visual
Studio 6编译器时,它不会在这种情况下生成编译错误:

- 我有一个继承自接口类的实现类A.它没有实现所有方法。
- 实现类A被声明为容器类中的数组。
容器类是用new创建的。


发布一些代码总是比描述相同。


#include< cstdlib>


class Base {

public:

virtual int donothing1(void)= 0;

virtual int donothing2(void)= 0;

};


A类:公共基地{

public:

virtual int donothing1(无效){

返回1;

}


//''donothing2''未实现

};


类容器{

私人:

一个obj [100];

};


int main(){

容器*包含=新容器;

delete包含;

返回EXIT_SUCCESS;

}

编译错误如下 -


d:\classA.cpp( 20):错误C2259:''A'':无法实例化抽象类

编译器不会产生任何错误,但我当然会在运行时出现运行时错误见面调用没有实现的hod(纯函数调用)或


除非

构建过程出现问题,否则无法调用没有实现的方法。尝试清理相关的

目标文件并重新构建整个东西。


东西)。如果容器类将A声明为指针(并在其上执行新的



编译器的行为完全取决于
$ b $的类型b对象你动态绑定到指向A的指针。


A * ptr; //编译器很开心你不是在这里实例化的东西。


ptr = new A; //假设没有实现A的所有方法,

//编译器会出错。

或作为非数组变量,编译器生成编译
错误,但不是如果它被声明为数组。

所以,我的问题是:它是编译器错误,


发布一些代码来理解更好的事情。

如果它没有发现创建了一个
抽象类(这是因为所有方法都没有实现)或者应该认为编译器无法找到这样的情况(即更复杂的情况)是正常的。




编译器绝对可以找到没有实现

类的所有方法的场景。


-

Karthik。 http://akktech.blogspot.com

''从我的电子邮件中删除_nospamplz给我发邮件。 ''


Bjorn schrieb:

我在C ++中使用接口来声明只使用纯虚拟方法的类。如果有人想要实现接口,他们需要从类中继承。如果实现类忘记实现某些方法,我通常会遇到编译错误(如果以某种方式创建类的话)。然而,在使用Visual
Studio 6编译器时,它不会在这种情况下生成编译错误:

- 我有一个继承自接口类的实现类A.它没有实现所有方法。
- 实现类A被声明为容器类中的数组。
容器类是用new创建的。

编译器不会产生任何错误,但是当调用没有实现的方法时,我当然会遇到运行时错误( 纯函数调用或
某事)。如果容器类将A声明为指针(并对其执行新的
)或非数组变量,则编译器会生成编译错误,但如果它被声明为数组则不会生成错误。 br />
所以,我的问题是:它是一个编译器错误,如果它没有发现创建了一个
抽象类(这是因为所有方法都不是
实现)?或者应该认为编译器无法找到这样的情况(即更复杂的情况)是正常的。

/ Bjorn




#include< list>


struct ABC {

virtual void x()= 0;

} ;


std :: list< ABC *>我的列表; //这没关系

std :: list< ABC> anotherlist; //这应该会产生编译时错误


Tom


Bjorn写道:

[ ...]
所以,我的问题是:它是编译器错误,如果它没有发现创建了一个
抽象类


_Created_?真?哪里?您声称容器类声明

A ...作为数组。你能说明你是怎么做到的吗?

(这是因为所有方法都没有实施)?或者应该认为编译器无法找到这样的情况(即更复杂的情况)是正常的。




------ ------------------------------例1:没什么大不了的。

struct ABC {//摘要

virtual void foo()= 0;

};


struct CC:ABC {//具体

void foo(){}

};


int main(){

ABC * pa; //指向ABC对象的指针,未初始化,未使用

}

---------------------- --------------例2:仍然没什么大不了的。

struct ABC {// abstract

virtual void foo()= 0 ;

};


struct CC:ABC {//具体

void foo(){}

};


int main(){

ABC * pa [10] = {0}; //指向ABC的指针数组,全部为0,未使用

}

-------------------- ----------------示例3:未定义的行为

struct ABC {// abstract

virtual void foo()= 0 ;

};


struct CC:ABC {//具体

void foo(){}

};


int main(){

ABC * pa; //一个未初始化的ABC指针

pa-> foo(); //尝试使用未初始化的指针 - BOOM!

}

--------------------- ---------------示例4:未定义的行为

struct ABC {// abstract

virtual void foo()= 0;

};


struct CC:ABC {//具体

void foo(){}

};


int main(){

ABC * pa [10]; //一系列未初始化的ABC指针

pa [0] - > foo(); //尝试使用未初始化的指针 - BOOM!

}

--------------------- ---------------示例5:没什么大不了的。

struct ABC {// abstract

virtual void foo()= 0 ;

};


struct CC:ABC {//具体

void foo(){}

};

#include< list>

int main(){

std :: list< ABC *> LST; //一个标准的ABC指针列表 - 未使用

}

---------------------- --------------

所有的例子都应该编译好(虽然我没有检查,只需键入

)。


正如您所看到的,如果没有尝试_instantiate_抽象

类,它仍然可能有未定义的行为,但没有到期

对纯函数的调用。


C ++语言禁止_ob $抽象的类_object_的_creation_。如果你的程序没有创建任何对象,它怎么能有
未定义的行为?如果你不在你的代码中创建任何对象,

编译器怎么知道你的意图是什么?


Victor


I''m using interfaces in C++ by declaring classes with only pure virtual
methods. If then someone wants to implement the interface they
needs to inherit from the class. If the implementing class forgets to
implement some method I normally get a compile error(if the class is created
in some way of course). When using the Visual
Studio 6 compiler however, it does not generate a compile error in this
case:

- I have a implementing class A that inherits from an interface class. It
has not implemented all methods.
- The implementing class A is declared as an array in a container class. The
container class is created with new.

The compiler do not generate any errors, but I will of course get a runtime
error when a method with no implementation is called("pure function call" or
something). If the container class declares A as a pointer(and performs new
on it) or as a non-array variable, then the compiler generates compile
errors, but not if it is declared as an array.

So, my question is: is it a compiler fault, if it does not find out that an
abstract class is created(which is the case here since all methods are not
implemented)? Or should it be considered as normal that the compiler can not
find out cases like this(i.e more complicated cases).

/Bjorn

解决方案

Bjorn wrote:

I''m using interfaces in C++ by declaring classes with only pure virtual
methods. If then someone wants to implement the interface they
needs to inherit from the class. If the implementing class forgets to
implement some method I normally get a compile error(if the class is created
in some way of course). When using the Visual
Studio 6 compiler however, it does not generate a compile error in this
case:

- I have a implementing class A that inherits from an interface class. It
has not implemented all methods.
- The implementing class A is declared as an array in a container class. The
container class is created with new.
Posting some code is always better than describing the same.

#include <cstdlib>

class Base {
public:
virtual int donothing1(void) = 0;
virtual int donothing2(void) = 0;
};

class A: public Base {
public:
virtual int donothing1(void) {
return 1;
}

//''donothing2'' not implemented
};

class Container {
private:
A obj[100];
};

int main() {
Container * contain = new Container;
delete contain;
return EXIT_SUCCESS;
}
The compiler errors out as follows -

d:\classA.cpp(20): error C2259: ''A'' : cannot instantiate abstract class


The compiler do not generate any errors, but I will of course get a runtime
error when a method with no implementation is called("pure function call" or
It is not possible to call a method with no implementation, unless
there is a problem with the build process. Try cleaning the relevant
object files and building the entire thing again.

something). If the container class declares A as a pointer(and performs new
on it)
The compiler behavious is entirely determined by the type of the
object you dynamically bind to a pointer to A.

A * ptr ; // compiler is happy. you are not
// instantiating anything here.

ptr = new A ; // Assuming not all methods of A are implemented,
// compiler would error out.
or as a non-array variable, then the compiler generates compile
errors, but not if it is declared as an array.

So, my question is: is it a compiler fault,
Post some code to understand things better.
if it does not find out that an
abstract class is created(which is the case here since all methods are not
implemented)? Or should it be considered as normal that the compiler can not
find out cases like this(i.e more complicated cases).



A compiler can definitely find a scenario where not all methods of a
class are implemented.

--
Karthik. http://akktech.blogspot.com .
'' Remove _nospamplz from my email to mail me. ''


Bjorn schrieb:

I''m using interfaces in C++ by declaring classes with only pure virtual
methods. If then someone wants to implement the interface they
needs to inherit from the class. If the implementing class forgets to
implement some method I normally get a compile error(if the class is created
in some way of course). When using the Visual
Studio 6 compiler however, it does not generate a compile error in this
case:

- I have a implementing class A that inherits from an interface class. It
has not implemented all methods.
- The implementing class A is declared as an array in a container class. The
container class is created with new.

The compiler do not generate any errors, but I will of course get a runtime
error when a method with no implementation is called("pure function call" or
something). If the container class declares A as a pointer(and performs new
on it) or as a non-array variable, then the compiler generates compile
errors, but not if it is declared as an array.

So, my question is: is it a compiler fault, if it does not find out that an
abstract class is created(which is the case here since all methods are not
implemented)? Or should it be considered as normal that the compiler can not
find out cases like this(i.e more complicated cases).

/Bjorn



#include <list>

struct ABC {
virtual void x() = 0;
};

std::list<ABC *> mylist; // this is OK
std::list<ABC> anotherlist; // this should generate a compile-time error

Tom


Bjorn wrote:

[...]
So, my question is: is it a compiler fault, if it does not find out that an
abstract class is created
_Created_? REALLY? Where? You claim that "the container class declares
A ... as an array". Could you show how you do that?
(which is the case here since all methods are not
implemented)? Or should it be considered as normal that the compiler can not
find out cases like this(i.e more complicated cases).



------------------------------------ example 1 : no big deal
struct ABC { // abstract
virtual void foo() = 0;
};

struct CC : ABC { // concrete
void foo() {}
};

int main() {
ABC *pa; // a pointer to ABC object, uninitialised, unused
}
------------------------------------ example 2 : still no big deal
struct ABC { // abstract
virtual void foo() = 0;
};

struct CC : ABC { // concrete
void foo() {}
};

int main() {
ABC *pa[10] = {0}; // an array of pointers to ABC, all 0, unused
}
------------------------------------ example 3 : undefined behaviour
struct ABC { // abstract
virtual void foo() = 0;
};

struct CC : ABC { // concrete
void foo() {}
};

int main() {
ABC *pa; // an uninitialised pointer to ABC
pa->foo(); // an attempt to use that uninitialised pointer - BOOM!
}
------------------------------------ example 4 : undefined behaviour
struct ABC { // abstract
virtual void foo() = 0;
};

struct CC : ABC { // concrete
void foo() {}
};

int main() {
ABC *pa[10]; // an array of uninitialised pointers to ABC
pa[0]->foo(); // an attempt to use an uninitialised pointer - BOOM!
}
------------------------------------ example 5 : no big deal
struct ABC { // abstract
virtual void foo() = 0;
};

struct CC : ABC { // concrete
void foo() {}
};
#include <list>
int main() {
std::list<ABC*> lst; // a standard list of pointers to ABC - unused
}
------------------------------------
All examples should compile fine (although I didn''t check, just typed
them in).

As you can see, if there is no attempt to _instantiate_ the abstract
class, it''s still possible to have undefined behaviour, but not due to
the call to the pure function.

The C++ language prohibits _creation_ of _object_ of a class that is
abstract. If your program doesn''t create any objects, how can it have
undefined behaviour? And if you don''t create any objects in your code,
how can the compiler know what your intentions are?

Victor


这篇关于编译器未检测到的抽象类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆