Author's mistakes: Visual C displaying Derived&Base destructor

  • (3 Pages)
  • +
  • 1
  • 2
  • 3

30 Replies - 2011 Views - Last Post: 29 February 2012 - 05:42 PM Rate Topic: -----

#1 mgrex  Icon User is offline

  • D.I.C Head

Reputation: 3
  • View blog
  • Posts: 188
  • Joined: 25-March 10

Author's mistakes: Visual C displaying Derived&Base destructor

Posted 25 February 2012 - 03:25 PM

Since i finally made it to a different chapter, thanks to the help of the volunteers of this forum, it seems the problem is software rather than syntax related.

I'm using Microsoft Visual C++ 2010 Express, and it require I use: system("pause"); before entering the return 0 or exit, statements. The author seems to use a different software/compiler which doesn't require system("pause").

This system("pause") [sp statement], seems to be the culprit in why the following program won't display all of the output, which is supposed to be:

We will now define a DerivedClass object.
This is the BaseClass constructor.
This is the DerivedClass constructor.
The program is now going to end.
This is the DerivedClass destructor.
This is the BaseClass destructor.

Due to the sp statement, the last 2 lines of are not displayed. Removing it, will get the last 2 lines to be displayed but the program will shutdown immediately after displaying the output.

I'd also like to use this post, to post problems related to programs example in the chapter of the text book.

Source code
// This program demonst rates the order in which bas and 
// derived class constructors and destructors are called. 
#include <iostream> 
using namespace std; 
 
//*******************************************
// BaseClass declaration
//******************************************* 

class BaseClass
{
public: 
	BaseClass()			// Constructor 
		{	cout << "This is the BaseClass constructor.\n";	} 
	~BaseClass()		// Destructor 
		{	cout<< "This is the BaseClass destructor.\n";	} 
}; 

//************************************* 
// DerivedClass declaration 
//*************************************
class DerivedClass : public BaseClass 
{ 
public: 
	DerivedClass()		// constructor 
		{	cout << "This is the DerivedClass constructor.\n";	} 
	
	~DerivedClass()		// Destructor 
		{	cout<<  "This is the DerivedClass destructor.\n";	} 

}; 

//************************************* 
// main function
//************************************* 
int main() 
{ 
	cout  << "We will now define a DerivedClass object.\n"; 

	DerivedClass object; 

	cout  << "The program is now going to end.\n"; 
	
	system("pause");
	return 0; 

}

This post has been edited by mgrex: 25 February 2012 - 06:41 PM


Is This A Good Question/Topic? 0
  • +

Replies To: Author's mistakes: Visual C displaying Derived&Base destructor

#2 simeesta  Icon User is offline

  • Deadly Ninja


Reputation: 219
  • View blog
  • Posts: 592
  • Joined: 04-August 09

Re: Author's mistakes: Visual C displaying Derived&Base destructor

Posted 25 February 2012 - 03:47 PM

Don't you need to include <cstdlib> to call system?

I get the ouput as described in your post (when i remove system). The system("pause"); just keeps the window open until you press a key, I don't think you acutally need it. What I think is happening is system pause waits for you to press a key to close, then as main returns it prints the two "missing" statements the closes immediately, so you just dont see it.

Heres a link that shows how to keep command line open without system("pause"); but I dont have windows so can't see if it works.

This post has been edited by simeesta: 25 February 2012 - 03:48 PM

Was This Post Helpful? 1
  • +
  • -

#3 alias120  Icon User is offline

  • The Sum over All Paths
  • member icon

Reputation: 122
  • View blog
  • Posts: 700
  • Joined: 02-March 09

Re: Author's mistakes: Visual C displaying Derived&Base destructor

Posted 25 February 2012 - 03:51 PM

Do not use system("pause"). Aside from the fact that it brings you additional overhead, you are making a native system call when this issue can be addressed within the domain of the language itself.

The following line of code will keep the screen displayed until an input is received.

std::cin.get();



EDIT: Visual Studio does not require that one uses system("pause"), which is the reason I mention using cin.get(). The author of your text book is not using system("pause") because it is bad practice to do so.

This post has been edited by alias120: 25 February 2012 - 04:04 PM

Was This Post Helpful? 2
  • +
  • -

#4 Karel-Lodewijk  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 449
  • View blog
  • Posts: 849
  • Joined: 17-March 11

Re: Author's mistakes: Visual C displaying Derived&Base destructor

Posted 25 February 2012 - 03:58 PM

Quote

Due to the sp statement, the last 2 lines of are not displayed. Removing it, will get the last 2 lines to be displayed but the program will shutdown immediately after displaying the output.


You are indeed correct, The last two lines are a result of the object in the main function being destroyed. This only happens the moment the main function ends, so after the pause.

A solution is putting an extra scope before the pause, i.e.:

int main() 
{ 
        {
	    cout  << "We will now define a DerivedClass object.\n"; 

	    DerivedClass object; 

	    cout  << "The program is now going to end.\n"; 
	
        }
	system("pause");
	return 0; 
}



This will cause the object to go out of scope and be destroyed before the pause.

But simeesta's solution is probably better long term as it doesn't force you to modify the code each time.

This post has been edited by Karel-Lodewijk: 25 February 2012 - 03:59 PM

Was This Post Helpful? 2
  • +
  • -

#5 eker676  Icon User is offline

  • Software Engineer
  • member icon

Reputation: 378
  • View blog
  • Posts: 1,833
  • Joined: 18-April 09

Re: Author's mistakes: Visual C displaying Derived&Base destructor

Posted 25 February 2012 - 04:28 PM

Visual studio has a "Start without debugging" option that automatically pauses the program after it finishes. Or you can run the program from the command line.
Was This Post Helpful? 1
  • +
  • -

#6 mgrex  Icon User is offline

  • D.I.C Head

Reputation: 3
  • View blog
  • Posts: 188
  • Joined: 25-March 10

Re: Author's mistakes: Visual C displaying Derived&Base destructor

Posted 25 February 2012 - 06:40 PM

Thanks alot for the useful responses. As i said in my original post, that I'd like to use this thread to over come why the author's programs examples won't run.

The following is program the author slightly modified to demonstrate the "redifining of a base class function".

Compile error message:
1>------ Build started: Project: 15_06, Configuration: Debug Win32 ------
1>  GradedActivity.cpp
1>c:\path\chapter 15\15_06\15_06\gradedactivity.cpp(7): error C2084: function 'char GradedActivity::getLetterGrade(void) const' already has a body
1>          c:\path\chapter 15\15_06\15_06\gradedactivity.h(32) : see previous definition of 'getLetterGrade'
1>  Generating Code...
1>  Compiling...
1>  Pr15-06.cpp
1>  Generating Code...
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========




GradedActivity.h
//GradedActivity class is designed to hold the numeric score  
//and letter grade of a graded activity. 

#ifndef GRADEDACTIVITY_H 
#define GRADEDACTIVITY_H 

// GradedActivity  class  declaration 
class GradedActivity 
{ 
private: 
	char letter;			// To hold the letter grade
	double score;			// To hold the numeric score 
	void determineGrade();	// Determines the letter grade

public:
	// Default constructor: initializes the score member variable to 0.0
	GradedActivity() 
		{	letter = ' ';	score = 0.0;} 
	
	/*// Constructor: accepts an argument for score.
	GradedActivity(double s) 
		{	score = s;	} */ //Originally from Pr-15-02

	// Mutator function:  accepts  an  argument  for  the  score variable
	void setScore(double s) 
		{	score = s;	determineGrade();	} 

	// Accessor functions: returns the letter grade that corresponds to the value in score
	double getScore() const 
		{	return score;	} 
	
	char getLetterGrade() const
		{	return letter;	}   //This following line was excluded from Pr15-02
};
#endif 


GradedActivity.cpp
#include  "GradedActivity.h "

//****************************************************** 
// Member  function  GradedActivity::getLetterGrade  
//******************************************************
char GradedActivity::getLetterGrade() const 
{ 
	char letterGrade;	//To  hold  the  letter  grade 
	
	if (score > 89)
		letterGrade = 'A';
	else  if  (score > 79) 
		letterGrade = 'B'; 
	else  if (score  >  69) 
		letterGrade = 'C'; 
	else  if (score  >  59) 
		letterGrade = 'D'; 
	else 
		letterGrade = 'F';

	return  letterGrade; 
}


CurvedAcitivity
#ifndef CURVEDACTIVITY_H 
#define CURVEDACTIVITY_H 
#include "GradedActivity.h"

class CurvedActivity : public GradedActivity 
{ 
protected: 
	double rawScore;	// Unadjusted score 
	double percentage;	// Curve  percentage  double  percentage; 
public: 
	// Default  constructor 
	CurvedActivity() : GradedActivity() 
	{	rawScore = 0.0;	percentage = 0.0;	}

	// Mutator  functions 
	void setScore(double s) 
		{	rawScore = s; 
			GradedActivity::setScore(rawScore * percentage);	} 
			//^statement calls the base class's version of the setScore function with the mathematical expression

	//****************************************************************
	//same name as 1 of the base class(GradedActivity) member functions
	//
	//****************************************************************
	void setPercentage(double c)	
		{  percentage = c;	} 

	//  Accessor  functions 
	double getPercentage() const 
		{	return  percentage;	} 

	double getRawScore() const 
		{	return rawScore;	} 
};
#endif 



Pr15-06
// This program demonstrates a class that redefines a base class tunction. 
#include <iostream> 
#include <iomanip>
#include "CurvedActivity.h" 
using namespace std; 

int main() 
{ 
	double  numericScore;	// To hold the numeric score 
	double  percentage;		// To hold curve percentage

	// Define a curvedActivity object. 
	CurvedActivity exam; 
	
	// Get the unadjusted score. 
	cout << "Enter the student's raw numeric score: "; 
	cin  >> numericScore; 

	// Get the curve percentage. 
	cout <<  "Enter the curve percentage for this student: ";
	cin  >>  percentage; 
	
	// Send  the  values  to  t he  exam  object. 
	exam.setPercentage(percentage); 
	exam.setScore(numericScore); 
	
	// Display  the  grade  data. 
	cout  <<  fixed  <<  setprecision(2); 
	cout  <<  "The  raw  score  is " << exam.getRawScore() << endl; 
	cout  <<  "The curved score is " << exam.getScore()  << endl ; 
	cout  <<  "The curved grade is " << exam.getLetterGrade()  <<  endl; 

	cin.get();
	return  0; 
} 

Was This Post Helpful? 0
  • +
  • -

#7 eker676  Icon User is offline

  • Software Engineer
  • member icon

Reputation: 378
  • View blog
  • Posts: 1,833
  • Joined: 18-April 09

Re: Author's mistakes: Visual C displaying Derived&Base destructor

Posted 25 February 2012 - 09:14 PM

getLetterGrade() is already defined on line 33 in the header file.

Delete line 33 in GradedActivity.h and place a semi colon after line 32.
Was This Post Helpful? 0
  • +
  • -

#8 mgrex  Icon User is offline

  • D.I.C Head

Reputation: 3
  • View blog
  • Posts: 188
  • Joined: 25-March 10

Re: Author's mistakes: Visual C displaying Derived&Base destructor

Posted 26 February 2012 - 12:59 PM

Yeah tried that, but a similar error arose.

1>------ Build started: Project: 15_06, Configuration: Debug Win32 ------
1>  GradedActivity.cpp
1>  Generating Code...
1>  Compiling...
1>  Pr15-06.cpp
1>  Generating Code...
1>Pr15-06.obj : error LNK2019: unresolved external symbol "private: void __thiscall GradedActivity::determineGrade(void)" (?determineGrade@GradedActivity@@AAEXXZ) referenced in function "public: void __thiscall GradedActivity::setScore(double)" (?setScore@GradedActivity@@QAEXN@Z)
1>C:\Path\Chapter 15\15_06\Debug\15_06.exe : fatal error LNK1120: 1 unresolved externals



Line 13 in GradedActivity.h seems to be culprit:
void determineGrade(); // Determines the letter grade

This post has been edited by mgrex: 26 February 2012 - 01:00 PM

Was This Post Helpful? 0
  • +
  • -

#9 simeesta  Icon User is offline

  • Deadly Ninja


Reputation: 219
  • View blog
  • Posts: 592
  • Joined: 04-August 09

Re: Author's mistakes: Visual C displaying Derived&Base destructor

Posted 26 February 2012 - 01:20 PM

determineGrade() isn't defined anywhere. The function doesn't exist but you declare it.

As for setscore(), it isn't static so you can't call it like this GradedActivity::setScore(rawScore * percentage); you have to call it on an object, not a class.

You might want to take a look at virtual functions.
Was This Post Helpful? 1
  • +
  • -

#10 mgrex  Icon User is offline

  • D.I.C Head

Reputation: 3
  • View blog
  • Posts: 188
  • Joined: 25-March 10

Re: Author's mistakes: Visual C displaying Derived&Base destructor

Posted 26 February 2012 - 10:45 PM

Not to come off as stubborn but are you sure there's no other alternative? The author doesn't touch on virtual functions until a dozen pages later. Thanks for the link though.
Was This Post Helpful? 0
  • +
  • -

#11 mgrex  Icon User is offline

  • D.I.C Head

Reputation: 3
  • View blog
  • Posts: 188
  • Joined: 25-March 10

Re: Author's mistakes: Visual C displaying Derived&Base destructor

Posted 27 February 2012 - 07:21 PM

After reading that posting by Sanchit Karve, it unfortunately didn't help much. Same with the following link: http://www.learncpp....ult-and-delete/

The farthest i got was inserting virtual on determineGrade statement in GradedActivity.h (Line 13).

Do I need a member function for "virtual void determineGrade();" for it? Or do i simply need to modify the contents of GradedActivity.cpp? From what i've seen it seems, after adding the virtual keyword to determineGrade, the next step would be to modify the derived class, CurvedActivity.h, by inserting the derived keyword some where.


GradedActivity.h
//GradedActivity class is designed to hold the numeric score  
//and letter grade of a graded activity. 

#ifndef GRADEDACTIVITY_H 
#define GRADEDACTIVITY_H 

// GradedActivity  class  declaration 
class GradedActivity 
{ 
private: 
	char letter;			// To hold the letter grade
	double score;			// To hold the numeric score 
	virtual void determineGrade();	// Determines the letter grade

public:
	// Default constructor: initializes the score member variable to 0.0
	GradedActivity() 
		{	letter = ' ';	score = 0.0;} 
	
	// Mutator function:  accepts  an  argument  for  the  score variable
	void setScore(double s) 
		{	score = s;	determineGrade();	} 

	// Accessor functions: returns the letter grade that corresponds to the value in score
	double getScore() const 
		{	return score;	} 
	
	char getLetterGrade() const;
		{	return letter;	}   //This following line was excluded from Pr15-02
};
#endif 


Program output is supposed to be:
Enter the student's raw numeric score: 87
Enter the curve percentage for this student: 1.06
The raw score is 87.00
The curved score is 92.22
The curved grade is A
Was This Post Helpful? 0
  • +
  • -

#12 r.stiltskin  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 1833
  • View blog
  • Posts: 4,927
  • Joined: 27-December 05

Re: Author's mistakes: Visual C displaying Derived&Base destructor

Posted 27 February 2012 - 07:53 PM

It's really very straightforward. Basically the implementation in the .cpp file was supposed to be for determineGrade. Go back to the code in Post #6. Then make these corrections:

in GradedActivity.h change line 13 to:
	char determineGrade() const;	// Determines the letter grade

changing its return type. And change line 26 to use the return value:
		{	score = s;	letter = determineGrade();	} 



in GradedActivity.cpp change line 1 to:
#include  "GradedActivity.h"
(eliminate the extra space at the end of the filename)
and change line 6 to:
char GradedActivity::determineGrade() const

so this becomes the implementation for determineGrade

I think that's about it.
Was This Post Helpful? 1
  • +
  • -

#13 Karel-Lodewijk  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 449
  • View blog
  • Posts: 849
  • Joined: 17-March 11

Re: Author's mistakes: Visual C displaying Derived&Base destructor

Posted 27 February 2012 - 07:57 PM

If virtual was not mentioned yet, then I doubt you are supposed to use one.

Anyway before trying fixed, learn to understand the error messages you get. You will make errors in your own code as well so you need to somewhat understand what they mean.

So the error message was:
Pr15-06.obj : error LNK2019: unresolved external symbol "private: void __thiscall GradedActivity::determineGrade(void)" (?determineGrade@GradedActivity@@AAEXXZ) referenced in function "public: void __thiscall GradedActivity::setScore(double)" (?setScore@GradedActivity@@QAEXN@Z)
C:\Path\Chapter 15\15_06\Debug\15_06.exe : fatal error LNK1120: 1 unresolved externals



First of all, notice this is a linking error (LNK). This means your program compiles just fine. This means that the code you have written is syntactically correct (all the , ; } { etc. are in the right place) but it's missing a definition that you promised would be available by declaring it. You really ought to keep your promises :)

It tells you exactly what is missing, a definition for:

private: void __thiscall GradedActivity::determineGrade(void)



So let's see where this function is coming from:

class GradedActivity {
    ...
    void determineGrade();  // Determines the letter grade
    ...
};



This is a function declaration (a promise that this function exists), but not a definition. A definition would have some body {...}, telling the computer what it actually does. So let's look for a definition, it is not with it's declaration in the .h file, the next likely candidate is the GradedActivity.cpp file. It is not there, so it so it is missing.

Now forgetting to define a function is not an error on it's own. Sure you promised it would be there and it isn't but if no-one is actually using it, then no harm done. But then we arrive at the second part of your error

referenced in function "public: void __thiscall GradedActivity::setScore(double)" (?setScore@GradedActivity@@QAEXN@Z)



It appears someone is using it. The setScore function to be exact.

	    void setScore(double s)
	        {   score = s;  determineGrade();   } 



Yes we definitely need a definition for that function.

So how do you fix this. If you know what it is supposed to do, you can define it yourself.

Add this to GradedActivity.cpp:
void GradedActivity::determineGrade() {
    //do something usefule
}



And the error will magically go away.

This post has been edited by Karel-Lodewijk: 27 February 2012 - 07:58 PM

Was This Post Helpful? 2
  • +
  • -

#14 r.stiltskin  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 1833
  • View blog
  • Posts: 4,927
  • Joined: 27-December 05

Re: Author's mistakes: Visual C displaying Derived&Base destructor

Posted 27 February 2012 - 08:10 PM

I just noticed the discussion from a few days ago about system("pause"); and so on.

Here's a link to a set of instructions I posted a while ago about configuring MSVC++ projects so that "Start Without Debugging" (Ctrl-F5) will be available. (Look at the bottom part of that post.)

I just have 1 thing to add to that. A few days ago I installed MSVC++ on a new laptop and much to my annoyance "Start Without Debugging" didn't appear in the Debug menu no matter how I set up the project. After wasting a lot of time it turned out that I had to go to Tools/Settings and check "Expert Settings" instead of the default which was "Basic Settings".
Was This Post Helpful? 1
  • +
  • -

#15 Karel-Lodewijk  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 449
  • View blog
  • Posts: 849
  • Joined: 17-March 11

Re: Author's mistakes: Visual C displaying Derived&Base destructor

Posted 27 February 2012 - 08:21 PM

I wouldn't actually mind that people put that system("pause") in there if they'd only include the right library to use the system function (stdlib.h/cstdlib), so compilation doesn't fail.

It's using something platform dependent in a platform dependent way.

This post has been edited by Karel-Lodewijk: 27 February 2012 - 08:24 PM

Was This Post Helpful? 0
  • +
  • -

  • (3 Pages)
  • +
  • 1
  • 2
  • 3