Hi,

I have been wrestling with this program all day and am looking for some help.

I have never separated a program up before into separate files (main.cpp, base.h and base.cpp).

What I'm trying to do is call a function from main() and have that function return a pointer to a new object.

Once the pointer has been returned, I'm trying to push it into the std::list.

The problem I've been having is this compile error:

illegal call of non-static member function

I have wrote a simple version of my program which reproduces the same problem:

main.cpp :

#include <iostream>
#include <list>
#include <string>
#include "base.h"
using namespace std;

int main()
{
	typedef list<Base *>BaseList;

	do{
		char choice;
		cout << "a) Create then add a base class pointer into the list" << endl;
		cin >> choice;
		cin.ignore();

		switch(choice)
		{
		case 'a':
			{
				//Create an object and return a pointer to that object
				//(I will be making many of these objects)
				Base::ReturnPtrToANewBaseClassObject();

				//push the returned pointer onto the std::list
				BaseList.push_back( ptr );

				cout << "Object now pushed onto list" << endl;
				break;
			}
		default:
			{
				cout << "You made an invalid choice" << endl;
				break;
			}
		}
	}
	while(true);

	system("pause");
}

base.h :

#ifndef BASE_H
#define BASE_H

#include <iostream>
#include <string>
using namespace std;

class Base
{
public:
	//constructor
	Base(string mystring);

	//Member Functions:
	Base * ReturnPtrToANewBaseClassObject();//Create an object and return a pointer to it

private:

protected:

	//Data Members common to all objects (abstract base class):
	string _mystring;

};
#endif

base.cpp :

#pragma once

#include <iostream>
#include <string>
#include "base.h"


//Base class contructor

Base::Base(string mystring)
{
	_mystring = mystring;
}

//Base class function
Base * ReturnPtrToANewBaseClassObject()
{
	//Build an object, and then return a pointer to that object
	//Wthin main() the pointer will be be pushed into the std:list

	string mystring;
	cout << "Value? " << endl;
	getline (cin, mystring);

	//Get a pointer to the new object
	Base *ptr = new Base(mystring);

	//return the pointer to main()
	return (ptr);
}

Here is what Visual Studio reports when I try to build:

------ Build started: Project: myproject, Configuration: Debug Win32 ------
Compiling...
main.cpp
c:\main.cpp(22) : error C2352: 'Base::ReturnPtrToANewBaseClassObject' : illegal call of non-static member function
c:\base.h(15) : see declaration of 'Base::ReturnPtrToANewBaseClassObject'
c:\main.cpp(25) : error C2143: syntax error : missing ';' before '.'
c:\main.cpp(25) : error C2143: syntax error : missing ';' before '.'
Build log was saved at "file://c:\Debug\BuildLog.htm"
myproject - 3 error(s), 0 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

I have a very similar program working when I use a single main.cpp file, but I want to stop using single files, and this problem has really been holding me back.

Hope you guys and gals can help me with this.

Thanks very much!!!

Carrots.

case 'a':
			{
				//Create an object and return a pointer to that object
				//(I will be making many of these objects)
				[B]Base::ReturnPtrToANewBaseClassObject();[/B]

				//push the returned pointer onto the std::list
				BaseList.push_back( ptr );

				cout << "Object now pushed onto list" << endl;
				break;
			}

This is the way that you would call a static class function. Static functions allow you to call a function belonging to the class without having an instance of the class created. However, you must use the static keyword when defining the function in the header file. See this for more information.


Also, the ReturnPtr....() function returns a pointer, but you are not storing this value. You could either do this on two lines like:

Base* ptr = Base::ReturnPtrToANewBaseClassObject();
BaseList.push_back( ptr );

or on one like

BaseList.push_back( Base::ReturnPtrToANewBaseClassObject() );

All that being said, I think you are going down a bad road here. What you are essentially doing is creating an instance of an object with some specific value. This is exactly the function of a constructor. I would recommend that you use a constructor to accomplish this. However, I wouldn't use cin inside of the constructor. Instead, in the main program ( or wherever it is needed ) i would request the input, and then pass the input string off to a constructor to create a new Base object. Something like:

Base::Base( string someStr )
{
    _mystring = someStr;
}

int main()
{
   string inStr;
   cout << "Give me input: " << flush;
   cin >> inStr;
   Base* ptr = new Base( inStr );
   // do whatever
   return 0;
}

I haven't compiled any of this, so it probably won't work out the door. However, this should give you some ideas

commented: Thanks for helping me out. thumbsup'jpg +1

hey I got it to work!

Thanks for your advice dusktreader,


took me a while, but I'm very happy none the less.


Thanks for taking the time buddy.

Appreciated

Carrots.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.