I have the function below in three base classes, one base, then one derived, and another derived from the second. I'm getting external resolution errors when I try to build it.

virtual void printtostream(ostream& out);

//Since it is a virtual function the above was not defined in any  of the class definitions. 
//My function, right before main, is this

ostream& operator << (ostream &out, telnumber &tn)
{
	tn.printtostream(out);
	return out;
}

This gives me three external resolution errors. What am I forgetting to do?

In the base class the function should be declared a pure virtual function virtual void printtostream(ostream& out) = 0; This will force one (or more) of the derived classes to provide the implementation for that function.

Okay, I made it a true virtual, but it tells me it can't instantiate the class telnumber (multiple times) because it is now an abstract (which I knew it would be with the =0 added)

So I tried a couple of implementations in the workingnumber.cpp and it's still happening. My very obvious deduction is that either my implementation is horribly wrong, or I"m doing it in the wrong place. I don't think it's the wrong place...and unless I miss my guess, I'll also have to define it in the cpp file for billing number...is that correct?

We are just guessing now. Post the code so that we can test see exactly what you have done (you can attach the *.cpp and *.h file(s) to your post)

Okay, here are the classes, in order, and in h/cpp order

class telnumber
{
public:
	telnumber();
	telnumber (string i_npa,string i_nxx,string i_line);
	~telnumber();
	void setnpa (string& newnpa);
	void setnxx (string& newnxx);
	void setline (string& newline);
	string getnpa();
	string getnxx();
	string getline();
	virtual void printtostream(ostream& out)=0;

private:
	string npa;
	string nxx;
	string line;

};


telnumber::telnumber()
	{
		npa="";
		nxx="";
		line="";
	}

	telnumber::telnumber (string i_npa,string i_nxx,string i_line)
	{

	}

	void telnumber::setnpa (string& newnpa)
	{
		npa=newnpa;
	}
	
	void telnumber::setnxx (string& newnxx)
	{
		nxx=newnxx;
	}
	
	void telnumber::setline (string& newline)
	{
		line=newline;
	}

	string telnumber::getnpa()
	{
		return (npa);
	}

	string telnumber::getnxx()
	{
		return (nxx);
	}

	string telnumber::getline()
	{
		return (line);
	}

	telnumber::~telnumber()
	{
	}

class worknumber : public telnumber
{
public:
	worknumber();
	worknumber(string i_npa, string i_nxx, string i_line, string i_name);
	~worknumber();
	void setname(string& newname);
	string getnewname();
	virtual void printtostream(ostream& out);

protected:
	string name;

};

worknumber::worknumber():
	telnumber("","",""),
	name ("")
{
}

worknumber::worknumber(string i_npa, string i_nxx, string i_line, string i_name):
	telnumber(i_npa, i_nxx, i_line)
{
}

void worknumber::setname(string& newname)
{
	name=newname;
}

string worknumber::getnewname()
{
	return (name);
}

void printtostream(ostream& out)
{
	//crappy implementation removed
}

worknumber::~worknumber()
{
}

class billnumber : public worknumber
{
public:
	billnumber();
	billnumber(string i_npa, string i_nxx, string i_line, string i_name,int numlines=0);
	~billnumber();
	void setnumlines();
	int getnumlines();
	virtual void printtostream(ostream& out);

protected:
	int numlines;
};

billnumber::billnumber():
	worknumber("","","","")
	{
}

billnumber::billnumber(string i_npa, string i_nxx, string i_line, string i_name, int numlines):
	worknumber(i_npa, i_nxx, i_line, i_name)
{
}
	
void billnumber::setnumlines()
{
	numlines=0;
}

int billnumber::getnumlines()
{
	return (numlines);
}
	
billnumber::~billnumber()
{
}


//and then main

ostream& operator << (ostream &out, telnumber &tn)
{
	tn.printtostream(out);
	return out;
}

int main()
{
	telnumber yournumber;
	telnumber paul("719","590","6768");
	telnumber bob("719","590", "6729");
	worknumber csstaff1 ("719","590","6732","Book Store");
	worknumber csstaff2 ("212","371","6940","Borland C++ Guru");
	worknumber csstaff3 ("405","612","3433","Visual C++ Expert");
	billnumber csdept ("719","590","6850","Dean of CS");
	billnumber library ("719","598","6708","Librarian");
	billnumber reception ("719","598","0200","Receptionist",35);
	cout << "Testing the overladen << operator with the virtual" << "printtostream()\n\n";
	cout << "The telephone numbers are: \n" << endl;
	cout << yournumber << endl;
	cout << paul << endl;
	cout << bob << endl;
	cout << "The working telephone numbers are: \n" << endl;
	cout << csstaff1 << endl;
	cout << csstaff2 << endl;
	cout << csstaff3 << endl;
	cout << "The billing telephone numbers are: \n" << endl;
	cout << csdept << endl;
	cout << library << endl;
	cout << reception << endl;
	cout << "Here endeth the hierarchy of the telephone!" << endl;

return 0;
}

line 105 needs the class soping in the name. You can not have just one function for all three classes -- you have to code one method for each class. Three classes, each class declared printtostream() so you must code each of the three methods, one for each class.

So even though I've declared the function to be pure virtual in telnumber, I still have to define it in telnumber cpp? I thought you didn't write an implementation for pure virtuals in the base class?

I understand about the scope, I just forgot to put it in...I did the same for billnumber

I have to work on a good implementation for the printtostream function also...so far I don't seem to be able to get it to work

line 163 prevents you from making it a pure virtual function. You can't create an object of a class that has a pure virtual function, as you have already found out. So my previous idea to make it pure virtual won't work.

Yes, I found out...lol...I took the =0 out to make it just a plain ol virtual again, fixed the scope resolution in all the class cpp files, and just left the implementation blank for the moment. That at least gives me a screen and some output.

I can't for the life of me figure out the implementation of those virtuals though, nothing I put in outputs anything from main except 172, 173, 177, 181, and 185. I need to figure out how to make it see the other lines as "inputs" to those functions and I don't know how to do that

I can't for the life of me figure out the implementation of those virtuals though, nothing I put in outputs anything from main except 172, 173, 177, 181, and 185. I need to figure out how to make it see the other lines as "inputs" to those functions and I don't know how to do that

Maybe the following helps ...

// telnumber
void telnumber::printtostream(ostream& out)
{
    out << "telnumber\n";
}

// worknumber
void worknumber::printtostream(ostream& out)
{
    telnumber::printtostream(out);
    out << "worknumber\n";
}

// billnumber
void billnumber::printtostream(ostream& out)
{
    worknumber::printtostream(out);
    out << "billnumber\n";
}

This is what that got me, but it's more than I had

from the console:

Testing the overladen << operator with the virtualprinttostream()

The telephone numbers are:

telnumber

telnumber

The working telephone numbers are:

telnumber
worknumber

telnumber
worknumber

telnumber
worknumber

The billing telephone numbers are:

telnumber
worknumber
billnumber

telnumber
worknumber
billnumber

telnumber
worknumber
billnumber

Here endeth the hierarchy of the telephone!
Press any key to continue . . .

Now you can tailor those functions so that the output is what you want it to be and in desired order. I.e. on a per-class basis decide what you want to output.

everything from about line 163 us what I want to output, but I can't seem to get it to do that.

everything I try is wrong in some way and won't even compile on the individual cpp files...and when hey do compile, I get the same blank lines

everything from about line 163 us what I want to output, but I can't seem to get it to do that.

everything I try is wrong in some way and won't even compile on the individual cpp files...and when hey do compile, I get the same blank lines

You need to devise something like ...

// telnumber
void telnumber::printtostream(ostream& out)
{
    // output npa, nxx and line
    out 
        << "npa: [" << npa << "]\n"
        << "nxx: [" << nxx << "]\n"
        << "line: [" << line << "]\n";
}
// worknumber
void worknumber::printtostream(ostream& out)
{
    // output the base class first ...
    telnumber::printtostream(out);

    // now worknumber data ...
    out << "name: [" << name << "]\n";
}

what do the semi colon and the brackets do? nm wasn't paying close enough attention....it still doesnt output the numbers...see below ... am I missing a function or something?

telnumber bob("719","590", "6729") is one of the lines in my main, yrt it doesnt take any of that as input

what do the semi colon and the brackets do?

Those are just printable characters in the output simply for display purposes, i.e. the data of a single telnumber object would display on screen as:

npa: [ value_of_npa_here ]
nxx: [ value_of_nxx_here ]
line: [ value_of_line_here ]

They have no functional impact whatsoever.

okay, thats what I thought...so now I know I'm doing something wrong...I'm missing something somewhere, because I can't seem to pull the values from main and print them....now originally, I thought that was because I was screwing up the function that was supposed to print them to the screen...but maybe it's in the setters in my class, am I doing those wrong? (they are on the previous page)

okay, thats what I thought...so now I know I'm doing something wrong...I'm missing something somewhere, because I can't seem to pull the values from main and print them....now originally, I thought that was because I was screwing up the function that was supposed to print them to the screen...but maybe it's in the setters in my class, am I doing those wrong? (they are on the previous page)

You need to assign the values in the ctor (they do not get assigned automatically)

telnumber::telnumber (string i_npa,string i_nxx,string i_line)
: 
  npa (i_npa),
  nxx (i_nxx),
  line (i_line)
{ }

awwww....I'm an idiot...I didn't even catch that. I knew I was missing an assignment or some other small detail

This question has already been answered. Start a new discussion instead.