virtual abstract functions

Discussion in 'C++' started by placid, Oct 11, 2005.

  1. placid

    placid Guest

    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
     
    placid, Oct 11, 2005
    #1
    1. Advertising

  2. * 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?

    --
    A: Because it messes up the order in which people normally read text.
    Q: Why is it such a bad thing?
    A: Top-posting.
    Q: What is the most annoying thing on usenet and in e-mail?
     
    Alf P. Steinbach, Oct 11, 2005
    #2
    1. Advertising

  3. placid

    Greg Guest

    placid wrote:
    > 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
     
    Greg, Oct 11, 2005
    #3
  4. placid

    John Carson Guest

    "Greg" <> wrote in message
    news:
    > placid wrote:
    >>
    >> int main(void)
    >> {
    >> A* aa = new B();
    >> }
    >>

    >
    > 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.

    --
    John Carson
     
    John Carson, Oct 11, 2005
    #4
  5. placid

    Greg Guest

    John Carson wrote:
    > "Greg" <> wrote in message
    > news:
    > > placid wrote:
    > >>
    > >> int main(void)
    > >> {
    > >> A* aa = new B();
    > >> }
    > >>

    > >
    > > 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.


    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
     
    Greg, Oct 11, 2005
    #5
  6. placid

    Jim Langston Guest

    "placid" <> wrote in message
    news:...
    > 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.
     
    Jim Langston, Oct 11, 2005
    #6
  7. placid

    Guest

    Greg wrote:
    > > > A* aa = new B;
    > > > ...

    > > A* aa = new B();
    > > is also correct.

    > 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; ?
     
    , Oct 11, 2005
    #7
  8. * Greg:
    > John Carson wrote:
    > > "Greg" <> wrote in message
    > > news:
    > > > placid wrote:
    > > >>
    > > >> int main(void)
    > > >> {
    > > >> A* aa =3D new B();
    > > >> }
    > > >>
    > > >
    > > > Note also the proper syntax to allocate a B object:
    > > >
    > > > int main()
    > > > {
    > > > A* aa =3D new B;
    > > > ...
    > > > }

    > >
    > >
    > > A* aa =3D 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.


    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.

    --
    A: Because it messes up the order in which people normally read text.
    Q: Why is it such a bad thing?
    A: Top-posting.
    Q: What is the most annoying thing on usenet and in e-mail?
     
    Alf P. Steinbach, Oct 11, 2005
    #8
  9. placid

    Greg Guest

    Jim Langston wrote:
    > "placid" <> wrote in message
    > news:...
    > > 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.


    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
     
    Greg, Oct 11, 2005
    #9
  10. placid

    placid Guest

    Jim Langston wrote:
    > "placid" <> wrote in message
    > news:...
    > > 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.


    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();

    >
    > 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.
     
    placid, Oct 12, 2005
    #10
  11. placid

    Greg Guest

    placid wrote:
    > Jim Langston wrote:
    > > "placid" <> wrote in message
    > > news:...
    > > > 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.

    >
    > 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
     
    Greg, Oct 12, 2005
    #11
  12. placid

    placid Guest

    Greg wrote:
    > placid wrote:
    > > Jim Langston wrote:
    > > > "placid" <> wrote in message
    > > > news:...
    > > > > 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.

    > >
    > > 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?


    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)
    >
    > Greg
     
    placid, Oct 12, 2005
    #12
  13. placid

    Guest

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

    btw, what does it mean?
     
    , Oct 12, 2005
    #13
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. DaKoadMunky
    Replies:
    4
    Views:
    557
    Lee Weiner
    Apr 20, 2004
  2. Uzytkownik
    Replies:
    3
    Views:
    601
    Uzytkownik
    Apr 3, 2005
  3. John Goche
    Replies:
    10
    Views:
    770
    Marcus Kwok
    Dec 8, 2006
  4. Arne Schmitz
    Replies:
    4
    Views:
    439
    Daniel Albuschat
    Jan 17, 2007
  5. Jess
    Replies:
    17
    Views:
    612
    James Kanze
    Jun 21, 2007
Loading...

Share This Page