473,599 Members | 3,118 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

abstract classes not detected by compiler

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

Jul 22 '05 #1
10 2547
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(2 0): 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. '
Jul 22 '05 #2
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
Jul 22 '05 #3
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
Jul 22 '05 #4
>It is not possible to call a method with no implementation, unless
there is a problem with the build process


Not necessarily true...

struct Abstract
{
Abstract()
{
NonVirtual();
}

void NonVirtual()
{
PureVirtual();
}

virtual void PureVirtual()=0 ;
};

struct Concrete : public Abstract
{
void PureVirtual()
{
}
};

int main()
{
Concrete c;

return 0;
}

Using MSVC++.NET a run-time error indicates that a pure virtual function was
called.

I don't know what the language standard says regarding this. I am guessing it
is undefined behavior? Does the standard discuss attempts to invoke pure
virtual functions directly or indirectly from a base class constructor (or
destructor?)
Jul 22 '05 #5
da*********@aol .com (DaKoadMunky) wrote in message news:<20******* *************** *****@mb-m27.aol.com>...
It is not possible to call a method with no implementation, unless
there is a problem with the build process
Not necessarily true...

struct Abstract
{
Abstract()
{
NonVirtual();
}

void NonVirtual()
{
PureVirtual();
}

virtual void PureVirtual()=0 ;
};

struct Concrete : public Abstract
{
void PureVirtual()
{
}
};

int main()
{
Concrete c;

return 0;
}

Using MSVC++.NET a run-time error indicates that a pure virtual function was
called.


It's normal: "Concrete" object vtable is not yet properly constructed.
I have seen the comments on this situation, but where it was ?...

I don't know what the language standard says regarding this. I am guessing it
is undefined behavior? Does the standard discuss attempts to invoke pure
virtual functions directly or indirectly from a base class constructor (or
destructor?)

Jul 22 '05 #6
Oleg Polikarpotchkin wrote:
da*********@aol .com (DaKoadMunky) wrote in message news:<20******* *************** *****@mb-m27.aol.com>...
It is not possible to call a method with no implementation, unless
there is a problem with the build process


Not necessarily true...

struct Abstract
{
Abstract()
{
NonVirtual();
}

void NonVirtual()
{
PureVirtual();
}

virtual void PureVirtual()=0 ;
};

struct Concrete : public Abstract
{
void PureVirtual()
{
}
};

int main()
{
Concrete c;

return 0;
}

Using MSVC++.NET a run-time error indicates that a pure virtual function was
called.

It's normal: "Concrete" object vtable is not yet properly constructed.
I have seen the comments on this situation, but where it was ?...

I don't know what the language standard says regarding this. I am guessing it
is undefined behavior? Does the standard discuss attempts to invoke pure
virtual functions directly or indirectly from a base class constructor (or
destructor? )


a constructor cannot call any virtual functions. so any call to a
virtual function will be non-virtual. In consequence calling a
pure virtual function should be rejected by the compiler (IIRC)...

Jul 22 '05 #7
Hi again,

I provide a code example below to clarify things. The compiler version I use
is:

Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8804 for 80x86

The following compiles without error, but of course gives a run time error
since all methods are not implemented.
#include "stdafx.h"

class Base {

public:

virtual void func1() = 0;

virtual void func2() = 0;

};

class SubClassToBase : public Base {

virtual void func1() {

int i = 7;

}

};

class Container {

public:

Base* getBase() {

return b;

}

private:

SubClassToBase b[1];

};

int main(int argc, char* argv[])

{

Container* c = new Container;

c->getBase()->func2();

// This will cause a runtime error, since

// func2() is not impemented

// The compiler does not generate error

return 0;

}

/Bjorn

"Karthik Kumar" <ka************ *******@yahoo.c om> wrote in message
news:417d6028$1 @darkstar...
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(2 0): 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. '

Jul 22 '05 #8
Bjorn wrote:
Hi again,

I provide a code example below to clarify things. The compiler version I use
is:

Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8804 for 80x86

The following compiles without error, but of course gives a run time error
since all methods are not implemented.
#include "stdafx.h"

class Base {

public:

virtual void func1() = 0;

virtual void func2() = 0;

};

class SubClassToBase : public Base {

virtual void func1() {

int i = 7;

}

};

class Container {

public:

Base* getBase() {

return b;

}

private:

SubClassToBase b[1];

};

int main(int argc, char* argv[])

{

Container* c = new Container;

c->getBase()->func2();

// This will cause a runtime error, since

// func2() is not impemented

// The compiler does not generate error

return 0;

}

/Bjorn


Checked with the two compilers that I have access to.

class Base {

public:

virtual void func1() = 0;
virtual void func2() = 0;

};

class SubClassToBase : public Base {

virtual void func1() {
int i = 7;
}
};

class Container { //g++ errors out here

public:

Base* getBase() {
return b;
}

private:
SubClassToBase b[1]; // VC++ .NET 2003 errors out here.
};

int main(int argc, char* argv[]) {

Container* c = new Container;
c->getBase()->func2();

// This will cause a runtime error, since
// func2() is not impemented
// The compiler does not generate error

return 0;
}
gcc 3.4.2.

C:\>g++ -ansi -pedantic pure_virtual.cp p
pure_virtual.cp p:17: error: cannot declare field `Container::b' to be of
type `SubClassToBase '
pure_virtual.cp p:17: error: because the following virtual functions
are abstract:
pure_virtual.cp p:6: error: virtual void Base::func2()
VC++ .NET is not happy either.

C:\pure_virtual .cpp(26) : error C2259: 'SubClassToBase ' : cannot
instantiate abstract class
due to following members:
'void Base::func2(voi d)' : pure virtual function was not defined
C:\pure_virtual .cpp(6) : see declaration of 'Base::func2'
<OT>

U:\>cl
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 13.10.3077 for 80x86
Copyright (C) Microsoft Corporation 1984-2002. All rights reserved.

</OT>

--
Karthik. http://akktech.blogspot.com .
' Remove _nospamplz from my email to mail me. '
Jul 22 '05 #9
> a constructor cannot call any virtual functions. so any call to a
virtual function will be non-virtual. In consequence calling a
pure virtual function should be rejected by the compiler (IIRC)...


Which rules from the specifications show this restriction?
Would you like to adjust your wording?

How does your statement fit to the descriptions in the chapter "Item
25: Virtualizing constructors and non-member functions" from the book
"More Effective C++"?

Regards,
Markus
Jul 22 '05 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

17
6632
by: Medi Montaseri | last post by:
Hi, Given a collection of similar but not exact entities (or products) Toyota, Ford, Buick, etc; I am contemplating using the Abstraction pattern to provide a common interface to these products. So I shall have an Abstract Base called 'Car' implemented by Toyota, Ford, and Buick. Further I'd like to enable to client to say Car *factory;
9
4632
by: Anon Email | last post by:
Hi people, I'm learning about header files in C++. The following is code from Bartosz Milewski: // Code const int maxStack = 16; class IStack
9
2294
by: Christian Christmann | last post by:
Hi, I've a class Handler which contains a STL list std::list<Abstract*> mAbstract; which is storing elements of the abstract class Abstract. Further this class has a getElement function to return a specific element of the list. The abstract class Abstract has some virtual pure function which are used with all concrete classes derived from it.
8
21712
by: Dev | last post by:
Hello, Why an Abstract Base Class cannot be instantiated ? Does anybody know of the object construction internals ? What is the missing information that prevents the construction ? TIA. Dev
2
9595
by: Dave Veeneman | last post by:
Is is legal to declare abstract members in non-abstract classes? How about non-abstract members in abstract classes? I am writing a base class with three derived classes. The base class will define the behavior for most, but not all of its members. The derived classes will define the behavior for the remaining members (the undefined members). I'd like to force the derived classes to implement the undefined members in the base class. I...
3
4302
by: Magne Ryholt | last post by:
I have a base class and a chain of derived classes. The base and its derived classes are all abstract except the last in chain (a concrete class). I want to provide some functionalities in the base class by defining a member as e.g. "protected virtual MyReturnClass MyMethod(){...}" The base classes, including the last (concrete class) adds on this functionality by defining members as e.g. "protected override MyReturnClass MyMethod(){......
4
1855
by: Eric | last post by:
I was wondering what people thought about the information found at: http://g.oswego.edu/dl/mood/C++AsIDL.html Specifically, I am interested in the following recommendation: ---- Since interface classes cannot be directly instantiated, yet serve as virtual base classes for implementations, the constructors should take no arguments and should be listed as protected. Also, for similar
17
3520
by: Jess | last post by:
Hello, If I have a class that has virtual but non-pure declarations, like class A{ virtual void f(); }; Then is A still an abstract class? Do I have to have "virtual void f() = 0;" instead? I think declaring a function as "=0" is the same
6
4022
by: Miguel Guedes | last post by:
Hello, I recently read an interview with Bjarne Stroustrup in which he says that pure abstract classes should *not* contain any data. However, I have found that at times situations are when it would be useful to have /some/ data defined in such an abstract class for reasons of forming a common block of data existing in or used by all descendant classes (see example below.) In such a case where a common block of data *always* exists,...
0
7992
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, weíll explore What is ONU, What Is Router, ONU & Routerís main usage, and What is the difference between ONU and Router. Letís take a closer look ! Part I. Meaning of...
0
7904
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
8398
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
8400
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
0
8267
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
5438
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
3940
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
1505
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
0
1250
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.