Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > inheritance problem

Reply
Thread Tools

inheritance problem

 
 
Gary Wessle
Guest
Posts: n/a
 
      11-10-2006
Hi

in the attempt below, I intend to use 2 derived classes whose objects
c'tor fires a base class method which build a string "main_menu" which
is a concatenation of the strings for each derived object c'tor
argument. ok, let me explain in a different language; but before, here
is the expected output

preform Thread task.
preform non-thread task.

why did not it happen?
thanks

// the code.

// task.h
#ifndef TASK_H
#define TASK_H
#include <string>
#include <vector>

class Task {
std::string main_menu;
public:
Task();
void mm_build(std::string);
void p_main_menu();
};

class Thr_task : public Task {
public:
Thr_task(std::string);
};


class No_thr_task : public Task {
public:
No_thr_task(std::string);
};

#endif


************************************************** **************
//task.cpp
#include <sstream>
using std::stringstream;
#include <fstream>
using std::ifstream;
#include <iostream>
using namespace std;

#include "task.h"

/* the base class */
Task::Task(){
p_main_menu();
}

void Task:_main_menu(){
cout << main_menu << endl;
}

void Task::mm_build(string s){
main_menu + ".\n" + s;
}


/* the drived class 1 */
Thr_task::Thr_task(string n)
{
Task::mm_build(n);
}

/* the drived class 2 */
No_thr_task::No_thr_task(string n)
{
Task::mm_build(n);
}


************************************************** **************
//main.cpp
#include <iostream>
using std::cout;
using std::endl;
#include "task.h"

int main() {
Thr_task t1("preform Thread task");
No_thr_task n1("preform non-thread task");
Task dummy;
}


 
Reply With Quote
 
 
 
 
mlimber
Guest
Posts: n/a
 
      11-10-2006
Gary Wessle wrote:
> Hi
>
> in the attempt below, I intend to use 2 derived classes whose objects
> c'tor fires a base class method which build a string "main_menu" which
> is a concatenation of the strings for each derived object c'tor
> argument. ok, let me explain in a different language; but before, here
> is the expected output
>
> preform Thread task.
> preform non-thread task.
>
> why did not it happen?
> thanks
>
> // the code.
>
> // task.h
> #ifndef TASK_H
> #define TASK_H
> #include <string>
> #include <vector>


You don't use vector.

>
> class Task {
> std::string main_menu;
> public:
> Task();
> void mm_build(std::string);


You should be passing all strings here by const reference. See:

http://www.parashift.com/c++-faq-lit....html#faq-18.1

> void p_main_menu();
> };
>
> class Thr_task : public Task {
> public:
> Thr_task(std::string);
> };
>
>
> class No_thr_task : public Task {
> public:
> No_thr_task(std::string);
> };
>
> #endif
>
>
> ************************************************** **************
> //task.cpp
> #include <sstream>
> using std::stringstream;
> #include <fstream>
> using std::ifstream;
> #include <iostream>
> using namespace std;


Why explicitly specify stringstream and ifstream when you also use the
whole std namespace, which brings both into scope anyway? Also, you
don't use either of those classes. Please post minimal code
(http://www.parashift.com/c++-faq-lit...t.html#faq-5.8) so as
not to confuse things.

>
> #include "task.h"


Stylistically, I prefer to put all using statements after *all* headers
so that the headers don't have extra (and perhaps unexpected) symbols
in the global namespace.

>
> /* the base class */
> Task::Task(){
> p_main_menu();
> }
>
> void Task:_main_menu(){
> cout << main_menu << endl;
> }
>
> void Task::mm_build(string s){
> main_menu + ".\n" + s;
> }
>
>
> /* the drived class 1 */
> Thr_task::Thr_task(string n)
> {
> Task::mm_build(n);
> }


There's no need to qualify mm_build here. There's no other mm_build in
this scope. Anywho, here's what this constructor implicitly does:

Thr_task::Thr_task(string n)
: Task()
{
Task::mm_build(n);
}

The base class constructor has already been called before you build the
menu. Why not have the Task constructor accept a string, which it then
uses to build a menu and, if you must, print it? Better yet, have the
derived constructors or the user call the print function.

> /* the drived class 2 */
> No_thr_task::No_thr_task(string n)
> {
> Task::mm_build(n);
> }
>
>
> ************************************************** **************
> //main.cpp
> #include <iostream>
> using std::cout;
> using std::endl;
> #include "task.h"
>
> int main() {
> Thr_task t1("preform Thread task");
> No_thr_task n1("preform non-thread task");
> Task dummy;
> }


Cheers! --M

 
Reply With Quote
 
 
 
 
Gary Wessle
Guest
Posts: n/a
 
      11-10-2006

another variation gave me more errors

************************************************** **************
#ifndef TASK_H
#define TASK_H
#include <string>
#include <vector>

class Task {
static std::string main_menu;
public:
Task(std::string);
void p_main_menu();
};

class Thr_task : public Task {
public:
Thr_task(std::string);
};


class No_thr_task : public Task {
public:
No_thr_task(std::string);
};

#endif

************************************************** **************

#include <sstream>
using std::stringstream;
#include <fstream>
using std::ifstream;
#include <iostream>
using std::cout;
using std::endl;
#include <string>
using std::string;

using namespace std;

#include "task.h"

/* the base class */
Task::Task(string s)
{
main_menu = main_menu + ".\n" + s; //<<<<<<< line 18
}

void Task:_main_menu(){
cout << main_menu << endl; //<<<<<<<<< line 22
}

/* the drived class 1 */
Thr_task::Thr_task(string n):
Task(n)
{
}

/* the drived class 2 */
No_thr_task::No_thr_task(string n):
Task(n)
{
}

************************************************** **************

#include <iostream>
using std::cout;
using std::endl;
#include "task.h"

int main() {
Thr_task t1("preform Thread task");
No_thr_task n1("preform non-thread task");
Task dummy("");
}

************************************************** **************

cd /home/fred/myProg/try/
make -k
g++ -gdwarf-2 -c -o task.o task.cpp
g++ -Wall -gdwarf-2 -o proj handle.o main.o swi_board.o task.o
task.o: In function `Task:_main_menu()':
/home/fred/myProg/try/task.cpp:22: undefined reference to `Task::main_menu'
task.o: In function `Task':
/home/fred/myProg/try/task.cpp:18: undefined reference to `Task::main_menu'
/home/fred/myProg/try/task.cpp:18: undefined reference to `Task::main_menu'
/home/fred/myProg/try/task.cpp:18: undefined reference to `Task::main_menu'
/home/fred/myProg/try/task.cpp:18: undefined reference to `Task::main_menu'
collect2: ld returned 1 exit status
make: *** [proj] Error 1

Compilation exited abnormally with code 2 at Fri Nov 10 14:11:35
 
Reply With Quote
 
Salt_Peter
Guest
Posts: n/a
 
      11-10-2006

Gary Wessle wrote:
> another variation gave me more errors
>
> ************************************************** **************
> #ifndef TASK_H
> #define TASK_H
> #include <string>
> #include <vector>
>
> class Task {
> static std::string main_menu;


don't use static members until you understand the implications and how
to initialize them.

> public:
> Task(std::string);


Always pass by reference, by const reference.
Otherwise copies can get very expensive.

> void p_main_menu();


Does that function modify the object: no
Make it const.

> };
>
> class Thr_task : public Task {
> public:
> Thr_task(std::string);


by const ref

> };
>
>
> class No_thr_task : public Task {
> public:
> No_thr_task(std::string);


by const ref

> };
>
> #endif
>
> ************************************************** **************
>
> #include <sstream>
> using std::stringstream;
> #include <fstream>
> using std::ifstream;
> #include <iostream>
> using std::cout;
> using std::endl;
> #include <string>
> using std::string;
>
> using namespace std;
>
> #include "task.h"
>
> /* the base class */
> Task::Task(string s)
> {
> main_menu = main_menu + ".\n" + s; //<<<<<<< line 18
> }


use the init list, see code below

>
> void Task:_main_menu(){
> cout << main_menu << endl; //<<<<<<<<< line 22
> }
>
> /* the drived class 1 */
> Thr_task::Thr_task(string n):
> Task(n)
> {
> }
>
> /* the drived class 2 */
> No_thr_task::No_thr_task(string n):
> Task(n)
> {
> }
>
> ************************************************** **************
>
> #include <iostream>
> using std::cout;
> using std::endl;
> #include "task.h"
>
> int main() {
> Thr_task t1("preform Thread task");
> No_thr_task n1("preform non-thread task");
> Task dummy("");
> }
>
> ************************************************** **************
>
> cd /home/fred/myProg/try/
> make -k
> g++ -gdwarf-2 -c -o task.o task.cpp
> g++ -Wall -gdwarf-2 -o proj handle.o main.o swi_board.o task.o
> task.o: In function `Task:_main_menu()':
> /home/fred/myProg/try/task.cpp:22: undefined reference to `Task::main_menu'
> task.o: In function `Task':
> /home/fred/myProg/try/task.cpp:18: undefined reference to `Task::main_menu'
> /home/fred/myProg/try/task.cpp:18: undefined reference to `Task::main_menu'
> /home/fred/myProg/try/task.cpp:18: undefined reference to `Task::main_menu'
> /home/fred/myProg/try/task.cpp:18: undefined reference to `Task::main_menu'
> collect2: ld returned 1 exit status
> make: *** [proj] Error 1
>
> Compilation exited abnormally with code 2 at Fri Nov 10 14:11:35


#include <iostream>
#include <string>

class Task {
std::string main_menu;
public:
Task(const std::string&);
void p_main_menu() const;
};

Task::Task(const std::string& s)
: main_menu(".\n" + s)
{
}

void Task:_main_menu() const
{
std::cout << main_menu << std::endl;
}

class Thr_task : public Task {
public:
Thr_task(const std::string&);
};

Thr_task::Thr_task(const std::string& s)
: Task(s)
{
}

class No_thr_task : public Task {
public:
No_thr_task(const std::string&);
};

No_thr_task::No_thr_task(const std::string& s)
: Task(s)
{
}

int main()
{
Thr_task tt("preform Thread task");
tt.p_main_menu();

No_thr_task ntt("preform non-thread task");
ntt.p_main_menu();

Task dummy("dummy");
dummy.p_main_menu();
}

/*
..
preform Thread task
..
preform non-thread task
..
dummy
*/

 
Reply With Quote
 
Gary Wessle
Guest
Posts: n/a
 
      11-10-2006
"mlimber" <(E-Mail Removed)> writes:

> Gary Wessle wrote:
> > Hi
> >
> > in the attempt below, I intend to use 2 derived classes whose objects
> > c'tor fires a base class method which build a string "main_menu" which
> > is a concatenation of the strings for each derived object c'tor
> > argument. ok, let me explain in a different language; but before, here
> > is the expected output
> >
> > preform Thread task.
> > preform non-thread task.
> >
> > why did not it happen?
> > thanks
> >
> > ...
> > #include <vector>

>
> You don't use vector.
>
> >
> > ...
> > void mm_build(std::string);

>
> You should be passing all strings here by const reference. See:
>
> http://www.parashift.com/c++-faq-lit....html#faq-18.1
>
> > void p_main_menu();
> > };
> > ...
> > #include <sstream>
> > using std::stringstream;
> > #include <fstream>
> > using std::ifstream;
> > #include <iostream>
> > using namespace std;

>
> Why explicitly specify stringstream and ifstream when you also use the
> whole std namespace, which brings both into scope anyway? Also, you
> don't use either of those classes. Please post minimal code
> (http://www.parashift.com/c++-faq-lit...t.html#faq-5.8) so as
> not to confuse things.
>
> >
> > #include "task.h"

>
> Stylistically, I prefer to put all using statements after *all* headers
> so that the headers don't have extra (and perhaps unexpected) symbols
> in the global namespace.
>
> >
> >...
> >
> > /* the drived class 1 */
> > Thr_task::Thr_task(string n)
> > {
> > Task::mm_build(n);
> > }

>
> There's no need to qualify mm_build here. There's no other mm_build in
> this scope. Anywho, here's what this constructor implicitly does:
>
> Thr_task::Thr_task(string n)
> : Task()
> {
> Task::mm_build(n);
> }
>
> The base class constructor has already been called before you build the
> menu. Why not have the Task constructor accept a string, which it then
> uses to build a menu and, if you must, print it? Better yet, have the
> derived constructors or the user call the print function.
>
> > /* the drived class 2 */
> > ...

>
> Cheers! --M


I tried many ways to get this to work, the best I can do is as follows
but still getting the error

************************************************** **************
cd /home/fred/myProg/try/
make -k
g++ -gdwarf-2 -c -o task.o task.cpp
g++ -Wall -gdwarf-2 -o proj handle.o main.o swi_board.o task.o
task.o: In function `Task:rint_mm()':
/home/fred/myProg/try/task.cpp:19: undefined reference to `Task::main_menu'
task.o: In function `Task':
/home/fred/myProg/try/task.cpp:14: undefined reference to `Task::main_menu'
/home/fred/myProg/try/task.cpp:14: undefined reference to `Task::main_menu'
/home/fred/myProg/try/task.cpp:14: undefined reference to `Task::main_menu'
/home/fred/myProg/try/task.cpp:14: undefined reference to `Task::main_menu'
collect2: ld returned 1 exit status
make: *** [proj] Error 1

Compilation exited abnormally with code 2 at Fri Nov 10 17:23:05


//task.h
************************************************** **************
#ifndef TASK_H
#define TASK_H
#include <string>

class Task {
static std::string main_menu;
public:
Task(std::string);
void print_mm();
};

class Thr_task : public Task {
public:
Thr_task(std::string);
void print_menu();
};


class No_thr_task : public Task {
public:
No_thr_task(std::string);
};

#endif

//task.cpp
************************************************** **************
1 #include <iostream>
2 #include <string>
3 using std::cout;
4 using std::endl;
5 using std::string;
6
7 using namespace std;
8
9 #include "task.h"
10
11 /* the base class */
12 Task::Task(string s)
13 {
14 main_menu = main_menu + ".\n" + s;
15 }
16
17 void Task:rint_mm(){
18
19 cout << main_menu << endl;
20 }
21
22 /* the drived class 1 */
23 Thr_task::Thr_task(const string n) :
24 Task(n)
25 {
26 }
27 void Thr_task:rint_menu(){
28 print_mm();
29 }
30
31 /* the drived class 2 */
32 No_thr_task::No_thr_task(const string n) :
33 Task(n)
34 {
35 }

//main.cpp
************************************************** **************
#include "task.h"

int main() {
Thr_task t1("preform Thread task");
No_thr_task n1("preform non-thread task");
Thr_task dummy(""); //only to print the main_menu
dummy.print_menu();
}
 
Reply With Quote
 
Gary Wessle
Guest
Posts: n/a
 
      11-10-2006
"Salt_Peter" <(E-Mail Removed)> writes:

> Gary Wessle wrote:
> > another variation gave me more errors

....

the idea I had in mind is to create objects of derived classes and
once I finish creating them, I then print the main_menu. not to print
the menu ever time I create an object. and that is why I thought to
use the static std::string main_menu.
once the menu prints it should show "as its items" the string passed
to the derived class c'tor.
 
Reply With Quote
 
Gary Wessle
Guest
Posts: n/a
 
      11-10-2006
"Salt_Peter" <(E-Mail Removed)> writes:

here is the code after all the fixes plus trying to use a static
member to hold the menu items from previous derived class objects.
since my idea is to initialize different derived class objects and
then print a menu listing them in the order they were created. i.e
1. preform Thread task.
2. preform non-thread task.
3. preform whatever.

thus I need to create the objects from their correct type like this

Thr_task t1("preform Thread task.");
No_thr_task n1("preform non-thread task.");
Whatever_type w1("preform whatever task.");

and if possible with the least typing "with out printing each time I
create an object" but only when I signal printing the whole menu.
maybe like
base_class bc("");
bc.print_mm();
cout << "please make a selection from the menu: " << endl;

I read a bit and fount that I have to set a static member and a static
member function to work with it, note below.

//task.h
************************************************** **************
#ifndef TASK_H
#define TASK_H
#include <string>

class Task {
static std::string main_menu;
public:
Task(const std::string&);
static void build_mm( const std::string& );
void print_mm() const;
};

class Thr_task : public Task {
public:
Thr_task(const std::string&);
void print_menu() const;
};


class No_thr_task : public Task {
public:
No_thr_task(const std::string&);
};

#endif





//task.cpp
************************************************** **************
1 #include <iostream>
2 #include <string>
3 using std::cout;
4 using std::endl;
5 using std::string;
6
7 using namespace std;
8
9 #include "task.h"
10
11 /* the base class */
12 Task::Task(const string& s)
13 {
14 build_mm(s);
15 }
16
17 void Task:rint_mm() const {
18 cout << main_menu << endl;
19 }
20
21 void Task::build_mm(const string& s){
22 main_menu = main_menu + ".\n" + s;
23 }
24
25 /* the drived class 1 */
26 Thr_task::Thr_task(const string& n) :
27 Task(n)
28 {
29 }
30 void Thr_task:rint_menu() const {
31 print_mm();
32 }
33
34 /* the drived class 2 */
35 No_thr_task::No_thr_task(const string& n) :
36 Task(n)
37 {
38 }




//main.cpp
************************************************** **************
#include "task.h"

int main() {
Thr_task t1("preform Thread task");
No_thr_task n1("preform non-thread task");
Thr_task dummy("");
dummy.print_mm();
}




//error
************************************************** **************

cd ~/myProg/try/
make -k
g++ -gdwarf-2 -c -o main.o main.cpp
g++ -Wall -gdwarf-2 -o proj handle.o main.o swi_board.o task.o
task.o: In function `Task::build_mm(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)':
/home/fred/myProg/try/task.cpp:22: undefined reference to `Task::main_menu'
/home/fred/myProg/try/task.cpp:22: undefined reference to `Task::main_menu'
task.o: In function `Task:rint_mm() const':
/home/fred/myProg/try/task.cpp:18: undefined reference to `Task::main_menu'
collect2: ld returned 1 exit status
make: *** [proj] Error 1

Compilation exited abnormally with code 2 at Fri Nov 10 20:35:08
 
Reply With Quote
 
Gary Wessle
Guest
Posts: n/a
 
      11-10-2006
another way I can do this is to make each task remember its menu item and
create a vector<Task*> in main.cpp, puch each item on it and loop and call
print_menu_item or even preform upon selection, i.e
vector<Task*> vTp.
*(vTp[i].print_menu_item)
that can do it, what you think?

 
Reply With Quote
 
=?iso-8859-1?q?Kirit_S=E6lensminde?=
Guest
Posts: n/a
 
      11-10-2006

Gary Wessle wrote:

> another way I can do this is to make each task remember its menu item and
> create a vector<Task*> in main.cpp, puch each item on it and loop and call
> print_menu_item or even preform upon selection, i.e
> vector<Task*> vTp.
> *(vTp[i].print_menu_item)
> that can do it, what you think?


It seems maybe you have your classes trying to do too much. Try to farm
off the menu generation to another set of classes to the task
execution. This will also make it easier to manage translation of the
menus should you need to do that. In any case the task class will be
simpler as it won't have to worry about display and the seperate
display classes will be simpler as they won't have to worry about
executing the classes.


K

 
Reply With Quote
 
Salt_Peter
Guest
Posts: n/a
 
      11-10-2006

Gary Wessle wrote:
> "Salt_Peter" <(E-Mail Removed)> writes:
>
> > Gary Wessle wrote:
> > > another variation gave me more errors

> ...
>
> the idea I had in mind is to create objects of derived classes and
> once I finish creating them, I then print the main_menu. not to print
> the menu ever time I create an object. and that is why I thought to
> use the static std::string main_menu.
> once the menu prints it should show "as its items" the string passed
> to the derived class c'tor.


How you plan to use your classes and objects are not my concern. I just
output the string to check whether these worked or not. What i might
suggest is simply use one of those classes and generate a vector of
menu items. I can see something like < > to inactivate them and <-> to
disactivate the item. You might implement a callback mechanism to
"talk" to the menu.

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
C++ Struct inheritance against class inheritance johnsonlau C++ 1 07-21-2008 04:58 PM
Interface inheritance vs Implementation inheritance. Daniel Pitts Java 27 02-27-2008 01:37 AM
Private Inheritance and Publice Inheritance karthikbalaguru C++ 9 09-10-2007 01:05 PM
mul. inheritance & overloading operator new/delete solved by virtual base inheritance? cppsks C++ 0 10-27-2004 07:49 PM
Private access modifier and Inheritance (Inheritance implementation in Java) maxw_cc Java 1 12-21-2003 11:38 AM



Advertisments