Solved

no appropriate default constructor available.

Posted on 2003-10-31
9
1,132 Views
Last Modified: 2007-12-19
Thanks for your comment, now I know that if I accept is (Position p[]) then I should use pointer to a Position* , if (float a[]) then I should use float*. And now I know that return an array. Thanks! 

Now I got another question I try to write the class MyOpenGLScene which inherits publicly from OpenGLScene. I try to add to the class an array which stores pointer to triangle and write a constructor which will accept the following parameters:
The name of the scene (as a char*), the width, the height , the color depth and a fullscreen flage(FALSE).
So I write like this:
 MyOpenGLScene::MyOpenGLScene (char* title, int width, int height, int bits, bool fullscreenflag)
{
      //this->title = title;
      //this->width = width;
      //this->heigh = heigh;
      //this->bits = bits;
      //this->fullscreenflag = fullscreenflag;
}
Then I got this error: C2512: 'OpenGLScene' : no appropriate default constructor available. So I don’t understand what going wrong, because I think the way I write is fine. I don’t know this error how to fix it, because I also new with C++, so can anyone explain to me why I will got this error? And what should I do if I meet with this kind of error again.

Following is my all class and code.
OpenGLScene.h
#define FALSE 0

class OpenGLScene {      
      HGLRC hRC;
      HWND hWnd;
      HINSTANCE hInstance;
      HDC hDC;
      BOOL done;
      bool fullscreen;
      MSG msg;
      GLvoid ReSizeGLScene(GLsizei width, GLsizei height);
      int InitGL(GLvoid);
      BOOL CreateGLWindow(char* title, int width, int height, int bits, bool fullscreenflag);
      
public:
      OpenGLScene (char* title, int width, int height, int bits, bool fullscreenflag);
      GLvoid KillGLWindow(GLvoid);
      virtual void addTriangle (Triangle *T) = 0;
      virtual int DrawGLScene(GLvoid) = 0;
      virtual void DrawTriangle (Triangle *T) = 0;
      int start ();
};

#endif


MyOpenGLScene.cpp
#include "OpenGLScene.h"

class MyOpenGLScene: public OpenGLScene
{
      Triangle* T;
      //char* title;
      //int width, heigh, bits;
      //bool fullscreenflag;

  public:
    //MyOpenGLScene (char* title, int width, int height, int bits, bool fullscreenflag);
      MyOpenGLScene (char* title, int width, int height, int bits, bool fullscreenflag);
      void addTriangle (Triangle *T);
      int DrawGLScene(GLvoid);
      void DrawTriangle (Triangle *T);
};

Triangle.h
#include "Position.h"
class Triangle
{
      float red,green,blue,point;
      Position pos[3];
            
public:
      Triangle (Position p[]);
      //~Triangle();
      void setColor(float red,float green,float blue);
      float getRed();
      float getGreen();
      float getBlue();
      Position* getVertices();
};

Hope someone can help me solve my problem. Thanks

From:sally
0
Comment
Question by:sally1980
  • 4
  • 3
9 Comments
 
LVL 8

Accepted Solution

by:
Exceter earned 20 total points
ID: 9662191
Try this,

class OpenGLScene {    
     HGLRC hRC;
    HWND hWnd;
    HINSTANCE hInstance;
    HDC hDC;
    BOOL done;
    bool fullscreen;
    MSG msg;
    GLvoid ReSizeGLScene(GLsizei width, GLsizei height);
    int InitGL(GLvoid);
    BOOL CreateGLWindow(char* title, int width, int height, int bits, bool fullscreenflag);
   
public:
    OpenGLScene(){}
    OpenGLScene (char* title, int width, int height, int bits, bool fullscreenflag);
    GLvoid KillGLWindow(GLvoid);
    virtual void addTriangle (Triangle *T) = 0;
    virtual int DrawGLScene(GLvoid) = 0;
    virtual void DrawTriangle (Triangle *T) = 0;
    int start ();
};

Exceter
0
 
LVL 15

Expert Comment

by:efn
ID: 9662197
See my comment on this question in the Programming area:

http://www.experts-exchange.com/Programming/Q_20784791.html
0
 
LVL 8

Expert Comment

by:Exceter
ID: 9664273
You also have to add a constructor to the OPenGLScene base class, as I demonstrated above, because it does not define a default constructor either. This is necessary because the constructor for the parent classes are called before the constructor for the derived class. For example,

class test1
{
      public:
            test1(int x){}
};

class test2 : public test1
{
      public:
            test2(){}
};

Will generate an error message similar to this, deending on your compiler,

Error E2251 C:\CPP\Test.cpp 16: Cannot find default constructor to initialize base class 'test1' in function test2::test2()

Similarly,

class test1
{
      public:
            test1(){}
};

class test2 : public test1
{
      public:
            test2(int x){}
};

Will generate an error similar to this,

>> Error E2285 C:\CPP\Test.cpp 24: Could not find a match for 'test2::test2()' in function main()

So, in actuality, you need to define a default constructor in both the base class and in the derived class.

Cheers!
Exceter
0
 
LVL 15

Expert Comment

by:efn
ID: 9664405
Just to clarify, Exceter and I have provided two different solutions--you can use either one, depending on what you need in the code that uses this class.  If you really need a default constructor, you can define one, as Exceter suggested, and if you don't really need a default constructor, you can use the constructor you already have, as I suggested.

--efn
0
IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

 
LVL 8

Expert Comment

by:Exceter
ID: 9664901
>> Exceter and I have provided two different solutions

Not really. I added a default constructor in the base class you suggesed adding one in the derived class, or not using a default constructor.

>> If you really need a default constructor, you can define one, as Exceter suggested, and if you don't really need a default constructor, you can use the constructor you already have, as
>> I suggested.

That's incorrect. The definition of a default constructor in the base class is manditory if you want to derive another class from it. The code will not compile if the base class does not have a default constructor, even if the dereived class does. For example,

class test1
{
    public:
         test1(int x){}
};

class test2 : public test1
{
    public:
          test2(){}
         test2(int y){}
};

Will give you an error similar to this,

Error E2251 C:\CPP\Test.cpp 16: Cannot find default constructor to initialize base class 'test1' in function test2::test2()
Error E2251 C:\CPP\Test.cpp 17: Cannot find default constructor to initialize base class 'test1' in function test2::test2(int)

The default constructor is necessary to construct the base class members before the derived class's consturctor is called and in like manner the destructor of test2 will be called before the destructor for test1. For example,

class test1
{
    public:
         test1(){ cout << "test1 being constructed." << endl; }
         ~test1(){ cout << "test1 being destroyed." << endl; }
};

class test2 : public test1
{
    public:
          test2(){ cout << "test2 being constructed." << endl; }
          ~test2(){ cout << "test2 being destroyed." << endl; }
};

...

test2 t;

-- output --
test1 being constructed.
test2 being constructed.
test2 being destroyed.
test1 being destroyed.

Therefore, the default constructor is required in the base class, as I demonstrated in my initial post, just so you can use the constructor that is already defined in MyOpenGLScene. If you want you can also define a default constructor for MyOpenGLScene but you dont have to. Although it is bad form not to do so.

Cheers!
Exceter
0
 
LVL 15

Expert Comment

by:efn
ID: 9665170
efn>> Exceter and I have provided two different solutions

Exceter>> Not really. I added a default constructor in the base class you suggesed adding one in the derived class, or not using a default constructor.

Yes, really.  I wasn't ingenious enough to suggest adding a default constructor, so I just suggested using the existing parameterized constructor.  However, my solution was defective because I guessed that the message was coming from an attempt to construct a derived object and I didn't notice that the derived class was trying to use a nonexistent default constructor for the base class.  So they really are two different solutions, mine just wouldn't work, and my statement that either would work was bogus.  Sorry, Sally!

efn>> If you really need a default constructor, you can define one, as Exceter suggested, and if you don't really need a default constructor, you can use the constructor you already have, as
efn>> I suggested.

Exceter>>That's incorrect. The definition of a default constructor in the base class is manditory if you want to derive another class from it. The code will not compile if the base class does not have a default constructor, even if the dereived class does.

I now agree that the original parameterized derived class constructor had a problem in itself and using it would not get the code to compile.  However, I don't agree with the statement that the base class must have a default constructor.  It's true that Exceter's example will not compile and it's true that adding a default constructor to the base class will get it to compile.  However, it's not true that this is the only way to get it to compile.  Here's another way:

class test2 : public test1
{
    public:
            test2() : test1(0){}
            test2(int y) : test1(y){}
};

This compiles without a default constructor in the base class test1.  Similarly, Sally could fix her code by having MyOpenGLScene initialize OpenGLScene in its initialization list.  Once again, we have a choice of two valid solutions!  Unless I blew it again.

--efn
0
 
LVL 8

Expert Comment

by:Exceter
ID: 9665259
>> However, I don't agree with the statement that the base class must have a default constructor.

True, you can do it that way. However, I think that your second example, although legal, has a design flaw because you are then required to do this in every class you derive from test1. This is annoying and easily forgotten. Also, the overhead of passing parameters to the constructor is probably slower than hardcoding them into the initialization list of a default constructor.

Exceter
0
 
LVL 9

Expert Comment

by:tinchos
ID: 10242417
No comment has been added lately, so it's time to clean up this TA.
I will leave the following recommendation for this question in the Cleanup topic area:

Accept: Exceter {http:#9662191}

Please leave any comments here within the next seven days.
PLEASE DO NOT ACCEPT THIS COMMENT AS AN ANSWER!

Tinchos
EE Cleanup Volunteer
0

Featured Post

Better Security Awareness With Threat Intelligence

See how one of the leading financial services organizations uses Recorded Future as part of a holistic threat intelligence program to promote security awareness and proactively and efficiently identify threats.

Join & Write a Comment

  Included as part of the C++ Standard Template Library (STL) is a collection of generic containers. Each of these containers serves a different purpose and has different pros and cons. It is often difficult to decide which container to use and …
Container Orchestration platforms empower organizations to scale their apps at an exceptional rate. This is the reason numerous innovation-driven companies are moving apps to an appropriated datacenter wide platform that empowers them to scale at a …
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.

762 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

22 Experts available now in Live!

Get 1:1 Help Now