tags:

views:

87

answers:

2

Hello, I am writing a GTKmm window program; the main window creates two buttons, one for English and one for Chinese. The user can click on the button to bring up a different window in the appropriate language. Currently I am having trouble initializing the multiple-item container inside the main window. It is an object of type MainWindowPane, which inherits Gtk::HBox.

When I try to make, the compiler issues the following error:

$ make 
g++ -g `pkg-config gtkmm-2.4 --cflags` -c MainWindow.cpp  
g++  -g -o QPI_frontend main.o MainWindow.o StartButton.o `pkg-config gtkmm-2.4 --libs`  
MainWindow.o: In function `MainWindow':  
/home/dmurvihill/Documents/QPI_frontend/MainWindow.cpp:9: undefined reference to   `MainWindowPane::MainWindowPane()'  
/home/dmurvihill/Documents/QPI_frontend/MainWindow.cpp:9: undefined reference to  `MainWindowPane::MainWindowPane()'  
collect2: ld returned 1 exit status  
make: *** [QPI_frontend] Error 1  

I am using the latest version of gcc with pkg-config to include the proper libraries. I am also a java person.

/*
 * MAIN_WINDOW.H
 * Responsible for creating "slave" RSED windows. Can create English or Chinese
 * versions of the demo, and can destroy them all with one click.
 */  
#ifndef MAINWINDOW_H  
#define MAINWINDOW_H  

#include <gtkmm/window.h>

//#include "SlaveWindow.h"
#include "StartButton.h"
#include "MainWindowPane.h"

class MainWindow : public Gtk::Window
{
public:
    MainWindow();   
private:
    MainWindowPane pane;
//  std::list<SlaveWindowThread> windows;       // Keeps track of all windows that have been created thus far.
    void destroyAllWindows();           // Iterates through the linked list and destroys each window.
};
#endif      //ifndef MAINWINDOW_H

/* 
 * MAIN_WINDOW.CPP
 *
 */  
#include "MainWindow.h"  
#include "MainWindowPane.h"  
#include "StartButton.h"  

MainWindow::MainWindow()// : /*list,*/ pane(/*list*/)
{
    pane;
}

void MainWindow::destroyAllWindows()
{
    //gtk_widget_destroy(*this);
    // TODO: Destroy all the other windows too.
}

/*
 * MAIN_WINDOW_PANE.H
 */  
#ifndef MAINWINDOWPANE_H  
#define MAINWINDOWPANE_H  

#include <gtkmm/box.h>
#include <gtkmm/button.h>

//#include "SlaveWindow.h"
#include "StartButton.h"

class MainWindowPane : public Gtk::HBox
{
public:
    MainWindowPane(/*&(std::list)*/);   
private:
    StartButton englishButton;      // Used to create a new RSED demo screen.
    StartButton chineseButton;      // Used to create a new RSED demo in chinese.
//  std::list<SlaveWindow> windows;     // Keeps track of all windows that have been created thus far.
    void destroyAllWindows();       // Iterates through the linked list and destroys each window.
};
#endif      //ifndef MAINWINDOWPANE_H

/* 
 * MAIN_WINDOW.CPP
 *
 */  
#include "MainWindowPane.h"  
#include "StartButton.h"  

MainWindowPane::MainWindowPane(/*&(std::list)*/) : 
    englishButton(StartButton::ENGLISH/*,&(std::list)*/), 
    chineseButton(StartButton::CHINESE/*,&(std::list)*/)
{
    pack_start(englishButton);
    englishButton.show();
    pack_start(chineseButton);
    chineseButton.show();
}

void MainWindow::destroyAllWindows()
{
    //gtk_widget_destroy(*this);
    // TODO: Destroy all the other windows too.
}
A: 

It's complaining that you are trying to call a default constructor for MainWindowPane that doesn't exist.

My guess is that MainWindowPane only defines ctors with parameters, and you are using it as a base class, and you either didn't define a ctor for the derived class, or the ctor you did define didn't call the base with parameters.

class MyDerived : public MainWindowPane
{
  public:
      MyDerived() {....}    // bad

      MyDerived(int x) : MainWindowPane(x)  // good
          {....} 

UPDATE:

OK, ignore the above (written before you posted the code). It seems to be complaining about this line"

MainWindow::MainWindow()// : /*list,*/ pane(/*list*/) 
{ 
    pane;     // Error HERE.
}

And I really have no idea what the purpose of that line is. You are just referencing a data member, without doing anything with it. It can probably be deleted.

UPDATE2: pane will be default constructed if you do nothing:

MainWindow::MainWindow()
{ 
}
James Curran
I forgot to put in my code at first. Oops!I've edited that in now. You can see that both the constructors I have defined the default constructor for MainWindowPane in the cpp file.Hope the code makes it a little clearer. I feel like I'm making some trivial mistake on the syntax somewhere (something that's easy for Java programmers to slip into!).
ILikeFood
That line was an attempt to call the default constructor for pane. I encounter a different error with pane();I moved the attempted constructor call into the function body because I encountered the same error when I tried to call pane in the initializer list. I subsequently forgot to move it back. I get the same error with this code: ... MainWindow::MainWindow() : pane(){}. With this code:MainWindow::MainWindow() : pane {} ... I get this error:MainWindow.cpp:9: warning: extended initializer lists only available with -std=c++0x or -std=gnu++0x' ...Thanks for all your help so far.
ILikeFood
+3  A: 

Undefined reference errors mean you either forgot to write define the missing function (by writing an implementation in the .cpp file), or you forgot to link the appropriate object file or library into the final binary.

In this case, it's the later reason. You need to include MainWindowPane.o in the linker command in your makefile:

g++  -g -o QPI_frontend main.o MainWindow.o StartButton.o `pkg-config gtkmm-2.4 --libs`
                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                        you need MainWindowPane.o in here
Ken Bloom
That's it. Added the source to my makefile, and the code compiled successfully. Thanks!Now, on to runtime debugging...
ILikeFood
@ILikeFood, remember to hit the checkmark next to the answer that worked for you to accept the answer.
Ken Bloom
Ahh, thank you. I tried to vote it up, too, but my acct is too new.
ILikeFood