virtual abstract functions

P

placid

Hi

if a have the following classes

class A
{
public:
A();
virtual ~A();
virtual string someFunction() const = 0;
}

class B:public A
{}

int main(void)
{
A* aa = new B();
}

I get this compiler error

main.cpp: In function `int main(int, char**)':
main.cpp:10: error: cannot allocate an object of type `A'
main.cpp:10: error: because the following virtual functions are
abstract:
B.h:30: error: virtual std::string B::someFunction() const


does anyone know whats this abou, because if i remove the 'const' in
the Base class it works but i wont the Base class to be abstract !


Thanks in advance
 
A

Alf P. Steinbach

* placid:
if a have the following classes

class A
{
public:
A();
virtual ~A();
virtual string someFunction() const = 0;
}

class B:public A
{}

int main(void)
{
A* aa = new B();
}

I get this compiler error

No you don't.

If you try to compile the above you get some other error messages.

Here's an example of what you actually get, using g++ 3.4.2:

koko.cpp:6: error: `string' does not name a type
koko.cpp:6: error: extra semicolon
koko.cpp:13: error: new types may not be defined in a return type
koko.cpp:13: error: two or more data types in declaration of `main'
koko.cpp:13: error: extraneous `int' ignored
koko.cpp:13: error: `main' must return `int'
koko.cpp:13: error: return type for `main' changed to `int'
koko.cpp: In function `int main(...)':
koko.cpp:14: warning: unused variable 'aa'

Here's another example, when '#include <string>' and 'using namespace std;'
are added on the top:

koko.cpp:16: error: new types may not be defined in a return type
koko.cpp:16: error: two or more data types in declaration of `main'
koko.cpp:16: error: extraneous `int' ignored
koko.cpp:16: error: `main' must return `int'
koko.cpp:16: error: return type for `main' changed to `int'
koko.cpp: In function `int main(...)':
koko.cpp:17: error: cannot allocate an object of type `B'
koko.cpp:17: error: because the following virtual functions are abstract:
koko.cpp:9: error: virtual std::string A::someFunction() const
koko.cpp:17: warning: unused variable 'aa'

Now for the error message you _claim_ for the above code, but which is
actually for code that you haven't shown:

main.cpp: In function `int main(int, char**)':
main.cpp:10: error: cannot allocate an object of type `A'
main.cpp:10: error: because the following virtual functions are
abstract:
B.h:30: error: virtual std::string B::someFunction() const

Study the error message.

What does it say?

That's one thing that's wrong in your actual code.

does anyone know whats this abou, because if i remove the 'const' in
the Base class it works

No it does not.

but i wont the Base class to be abstract !

Why?
 
G

Greg

placid said:
Hi

if a have the following classes

class A
{
public:
A();
virtual ~A();
virtual string someFunction() const = 0;
}

class B:public A
{}

int main(void)
{
A* aa = new B();
}

I get this compiler error

main.cpp: In function `int main(int, char**)':
main.cpp:10: error: cannot allocate an object of type `A'
main.cpp:10: error: because the following virtual functions are
abstract:
B.h:30: error: virtual std::string B::someFunction() const


does anyone know whats this abou, because if i remove the 'const' in
the Base class it works but i wont the Base class to be abstract !


Thanks in advance

Class B must implement someFunction for the class to be instantiable:

class B : public A
{
public:
virtual std::string someFunction() const
{
return "";
}
};

Note also the proper syntax to allocate a B object:

int main()
{
A* aa = new B;
...
}

Greg
 
J

John Carson

Greg said:
Note also the proper syntax to allocate a B object:

int main()
{
A* aa = new B;
...
}


A* aa = new B();

is also correct. See section 5.3.4/15 of the standard. The use of () means
that the object is value initialized.
 
G

Greg

John said:
A* aa = new B();

is also correct. See section 5.3.4/15 of the standard. The use of () means
that the object is value initialized.

Yes, the parentheses are legal in this new expression. But my point was
that the parentheses are completely superfluous when allocating an
instance of a class type. The object is default-initialized without the
parentheses, the object is default-initialized with the parentheses, so
their presence in the statement has no effect on its meaning.

The economy of expression principle holds that only those operators
needed to complete an expression should appear in it. In other words,
it is not a good idea to pepper one's code with aesthetically pleasing
operators that otherwise contribute nothing to its meaning. Doing so
makes the program harder to understand, since someone examining the
code must first decide whether an operator in a statement is performing
some necessary operation, or whether it can be excluded from analysis.

More importantly, superfluous operators in one context may suddenly
become meaningful in slightly different contexts and do so in
surprising ways. Even in a new expression, the Standard warns that the
presence of parentheses can have surprising effects (§5.3.4/3) - which
is another argument not to use parentheses indiscriminately in a C++
program, but to use them only on an as-needed basis.

Greg
 
J

Jim Langston

placid said:
Hi

if a have the following classes

class A
{
public:
A();
virtual ~A();
virtual string someFunction() const = 0;
}

class B:public A
{}

int main(void)
{
A* aa = new B();
}

I get this compiler error

main.cpp: In function `int main(int, char**)':
main.cpp:10: error: cannot allocate an object of type `A'
main.cpp:10: error: because the following virtual functions are
abstract:
B.h:30: error: virtual std::string B::someFunction() const


does anyone know whats this abou, because if i remove the 'const' in
the Base class it works but i wont the Base class to be abstract !


Thanks in advance

virtual string someFunction() const = 0;

This is called "pure virtual". Pure virtual means there is no definition of
the method in the base class, and any class that is derived from the base
class MUST define this method. Your class B did not define this method.
Which is what the compile error is yelling about.

Either:
1. Don't make the method pure virtual so you dont' have to define it in the
derived class (remove the = 0 ) or
2. Define the method in your derived class B.
 
M

makc.the.great

Greg said:
Yes, the parentheses are legal in this new expression. But... Doing so
makes the program harder to understand, since someone examining the
code must first decide whether an operator in a statement is performing
some necessary operation, or whether it can be excluded from analysis.

More importantly, superfluous operators in one context may suddenly
become meaningful in slightly different contexts and do so in
surprising ways. Even in a new expression, the Standard warns that the
presence of parentheses can have surprising effects (§5.3.4/3) - which
is another argument not to use parentheses indiscriminately in a C++
program, but to use them only on an as-needed basis.

are you saying that B::B() will not be called if I do new B; ?
 
A

Alf P. Steinbach

* Greg:
Yes, the parentheses are legal in this new expression. But my point was
that the parentheses are completely superfluous when allocating an
instance of a class type. The object is default-initialized without the
parentheses, the object is default-initialized with the parentheses, so
their presence in the statement has no effect on its meaning.

In this particular case, yes. For a POD, no. The problem is that popular
compilers such as Microsoft's do not adhere to the standard in this respect.
 
G

Greg

Jim said:
virtual string someFunction() const = 0;

This is called "pure virtual". Pure virtual means there is no definition of
the method in the base class, and any class that is derived from the base
class MUST define this method. Your class B did not define this method.
Which is what the compile error is yelling about.

Neither point is completely accurate. There may or may not be a
definition of the pure virtual function in the base class. If the
program ever calls the pure virtual method in the base class
explicitly, then the pure virtual function must be defined.
Furthermore, a derived class is not obligated to define a pure virtual
method it inherits. A derived class can declare also declare the method
pure virtual and thereby become an abstract class like its base.
Either:
1. Don't make the method pure virtual so you dont' have to define it in the
derived class (remove the = 0 ) or
2. Define the method in your derived class B.

There is also a third option just mentioned: B declares the method pure
virtual itself.

Greg
 
P

placid

Jim said:
virtual string someFunction() const = 0;

This is called "pure virtual". Pure virtual means there is no definition of
the method in the base class, and any class that is derived from the base
class MUST define this method. Your class B did not define this method.
Which is what the compile error is yelling about.

yes i have already defined the pure virtual function in the derived
class but the compiler still complains about not being able to make a
A* aa = new B();
 
G

Greg

placid said:
yes i have already defined the pure virtual function in the derived
class but the compiler still complains about not being able to make a
A* aa = new B();

Then show us the code :).

It's likely that you have actually overloaded and not overriden the
pure virtual function. Did you remember the const in the method's
declaration, for instance?

Greg
 
P

placid

Greg said:
Then show us the code :).

It's likely that you have actually overloaded and not overriden the
pure virtual function. Did you remember the const in the method's
declaration, for instance?

dude you have just fixed my problem. Thanks a lot man..

(i forgot the const in the member function definition.I thought it
didnt matter if you had the keyword const in the derived class method
definition)
 
M

makc.the.great

Did you remember the const in the method's declaration, for instance?

btw, what does it mean?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,055
Latest member
SlimSparkKetoACVReview

Latest Threads

Top