Hy there, I'm a newbie so be patient pls.

I have a small but useful class (let's call it Class1), and another class, more complex (let's call it Class2). I need to use in the Class2 instances of the Class1. I need to declare objects of Class1 both in private and in public section of Class2, and to initialize those objects in the constructor area of Class2, because all functions in the second class will access members of objects of type Class1.
All I get is errors.

Hy there, I'm a newbie so be patient pls.

I have a small but useful class (let's call it Class1), and another class, more complex (let's call it Class2). I need to use in the Class2 instances of the Class1. I need to declare objects of Class1 both in private and in public section of Class2, and to initialize those objects in the constructor area of Class2, because all functions in the second class will access members of objects of type Class1.
All I get is errors.

What are the errors? Where is the code? It could be all sorts of things.

When I made my "Tile" game I ran into the same problem.

I had a class called Tile and it held information for 1 square. Then I had a class called Board and this had a vector of Tiles within it.

The problem that I had was that if I had a constructor in my Board class it would give me an error saying that I cannot declare Tile or something.

Here is my really quick example with CLASS1 being used in CLASS2. I hope this solves any problems.

#include <iostream>
#include <vector>
#include <string>

using namespace std;
////////////////////////////////////

class CLASS1
{
	string name;
	
	public:
	CLASS1(string xname);
	string getName();
};

CLASS1::CLASS1(string xname)
{
	name = xname;
}

string CLASS1::getName()
{
	return name;
}

///////////////////////////////////////
class CLASS2
{
	vector<CLASS1> names;
	
	public:
	
	void addName(CLASS1 name);
	CLASS1 getName(int x);
};

void CLASS2::addName(CLASS1 name)
{
	names.push_back(name);
}

CLASS1 CLASS2::getName(int x)
{
	return names[x];
}

/////////////////////////////////

int main()
{
	CLASS1 name = CLASS1("Sean");
	
	CLASS2 names;
	names.addName(name);
	
	cout << names.getName(0).getName() << endl;
		
	system("PAUSE");
	return 0;	
}

This is an example of structure that I need to create. Errors are various, adding a default empty constructor shifts the error down a little, but does no good

#include <iostream>
using namespace std;

class class1{
	public:
	int variab;
	//constructor
	class1 (int h){variab=h;}
};

class class2{
	public:
	class1 obj1;//public object 1
	//constructor
	class2(int i){ 
		class1 obj1(99);//constructing object 1
		cout<<i+obj1.variab;//using obj1
	};
	private:
	//
	//more functions using obj1
	//
};


int main()
{
	//call to constructor class2
	class2 obj2(100);
	//calling constructor shoud output "199"
	return 0;
}


ERROR RETURNED:
error: no matching function for call to ‘class1::class1()’

This is the same error that I got when you try to a class inside of another class.

What I did was I used a constructor for class1 and a add() function for class2 instead of a constructor.

An add() function to do the adding is no good for me since I used add just as an example (the real code has about 5000 lines). I need to use the Class1 as a data type (as described in most C++ manuals), and I need to use this type for members (MANY MEMBERS) of the Class2. Is a simple imbrication model, (not even imbrication, more like a def type) that I successfully used in older languages, but for some syntax reason here is not working.
I see no workarround, and also I can see it functioning in classes like IFSTREAM, where you can declare ifstream myfile; in the public section of your own class, and call the ifstream myfile(test); constructor later, in your own constructor of your own class.
I'm missing something, and I do not know what......

OK I think I figured it out.

#include <iostream>
#include <string>

using namespace std;
////////////////////////////////////

class CLASS1
{
	string name;
	
	public:
	
	CLASS1();
	CLASS1(string xname);
	
	string getName();
};

CLASS1::CLASS1()
{
}

CLASS1::CLASS1(string xname)
{
	name = xname;
}

string CLASS1::getName()
{
	return name;
}

///////////////////////////////////////
class CLASS2
{
	CLASS1 names;
	
	public:
	
	CLASS2();
	CLASS2(CLASS1 xclass1);
	CLASS1 getName();
};

CLASS2::CLASS2()
{
}

CLASS2::CLASS2(CLASS1 xclass1)
{
	names = xclass1;
}

CLASS1 CLASS2::getName()
{
	return names;
}

/////////////////////////////////

int main()
{
	CLASS1 name("Sean");
	
	CLASS2 names(name);
	
	cout << names.getName().getName();
	
		
	system("PAUSE");
	return 0;	
}

The problem was that when you make your own constructor it deletes the default constructor. All you have to do is remake the default CLASS1() and it should work.

First of all, I want to thank you for the answer. Unfortunatelly most of the code you've sent does not answer to my problem:
1)I'll never use CLASS2(CLASS1 xclass1); since class2 object must be constructed in my case with many int like parameter (6 to 8 to be exact), not with one of type class1 (if I got the code corectly). Actually class1 will never be used in main at all.
2)CLASS1 CLASS2::getName() is not a member function of class2 that returns a class1 type result? I will never use this either.
If you would be so kind to try my code and maybe give me some suggestions, I will truly appreciate it. If you would like I can modify declarations and implementation to be separate, if the programming style is bothering you...
Thank you very much

Yeah sorry I should have been using your code.

Anyways I made this change to class1 and it worked.

class class1{
	public:
	int variab;
	//constructor
	class1(){} // add the new default constructor
	class1 (int h){variab=h;}
};

Wonderful, got rid of the error, but still not working! If I add a function in the class2 object:

    void coutagain(){
cout<<obj1.variab;        
}

and try to call it from main:

obj2.coutagain();

I've got a random number, as if the object obj1 declared as a part of the obj2 structure is no more......

Any idea?

Edited 3 Years Ago by Nick Evan: Fixed formatting

The reason why its outputting a random number is because it has not been assigned a value. The class2 constructor is making a new variable obj1 in its own scope.

for example

int i = 0;
int x = 0;
if( x >= 0 )
{
	int i = 2;
}
cout << i << endl;

the output to this is 0 because it all has to do with scopes

So to fix your problem you need to make a function to assign a value to obj1 because you only get to run a classes constructor once.

example

void setValue(int i)
{
	obj1.variab = i;
}

not sure if this is what you want to do but it works.

On some compilers (not g++) there is an warning: the variable is used unitialized. That is a strange behaviour, since the object obj was declared in public section of class2, and obj1 was initialized in the class2 constructor when obj2 was called............
It really makes no sens to me. And I ran out of coffee.

Yea, thanks, but it shouldn't be like this, since it is declared as a member, isn't it?

The last 3 posts in the thread just vanished....
So the problem now summarizes as this:
Why a member variable declared in public (of a class) and initialized in the constructor of the same class is visible from main, and an object declared , initialized and called in the same way is not?!

This might be your source of error.

class2(int i)
{ 
	class1 objxx(99);
	obj1 = objxx;//constructing object 1
	obj1.variab += i;
	cout << obj1.variab;//using obj1
}

This will actually assign your obj1 variable within class2. Before it was just making a temp variable during your constructor runtime.

Look like working. I'll extensevely test it later.
So the conclusion is this:
in an object type variable case, declaring the object is not enough, because calling the constructor will generate a different, local (non-public) object. Logic it would have been to be able to call the constructor like this:
obj1.class1(99);
avoiding redeclaration of type, but that is not possible. Maybe Bjarne Stroustrup knows why.....
Till then, for every object I have, I must declare a new fake one...... :((

This is a serious C++ concept bug. I'll put it on my C++ bugs list. When published, I'll definitely get an Emmy. Or Grammy, or something.

Thank you for your time and patience.
It is highly appreciated.

Sorry came a bit late to this thread.

The problem is that you are not using initilizers. Try this:
It disposes of the need to have a default constructor class1(). The important thing to remember is that the code in the { } after the constructor is run AFTER the initializers are run. So you should prefer setting things immediately rather than in that code block.

I have changed some of your variable names since I think you have confused yourself with the nearly identical names.

I have added standard references, it changes nothing in the sence of the code, but means that intermediate copies are not made. (which is normally bad).

#include <iostream>
#include <string>

////////////////////////////////////
class CLASS1
{
private:

  std::string name;

public:

  CLASS1(const std::string&);
  CLASS1(const CLASS1&);              // Always provide a copy constructor
  const std::string& getName() const { return name; }
};


CLASS1::CLASS1(const std::string& xname) :
  name(xname)
{}

CLASS1::CLASS1(const CLASS1& A) :
  name(A.name)
{}


///////////////////////////////////////
class CLASS2
{
private:

  CLASS1 c1object;

public:

  CLASS2();  
  CLASS2(const CLASS1&);
  // added a return reference + const

  const CLASS1& getC1() const { return c1object; } 
};

// this sets with the null name
CLASS2::CLASS2() :
  c1object("nullname")
{}

CLASS2::CLASS2(const CLASS1& xclass1) :
  c1object(xclass1)
{}


/////////////////////////////////

int main()
{
  CLASS1 c1Item("Sean");

  CLASS2 c2Item(c1Item);

  std::cout << "C2 == "<<c2Item.getC1().getName()<<std::endl;

  return 0; 
}

Edited 3 Years Ago by mike_2000_17: Fixed formatting

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