How to give class as argument without making copies?

Hi!

Such a problem... imagine such a code:
1
2
3
4
5
6
7
8
9
10
class Test1
{
public:
  Test1();//an empty(fake) constructor
  ~Test1();
  Initiate(); // the real constructor
  /*some functions here*/
private:
  Test2 *testing;
};

Let in be, that class Test2 is the same as Test1. Then, we have some class 3. Let it be, that even Test3 is the same, exept that thing, that it takes in constructor Test2 as an agrument. Now, why happens, that is doesn't get a reference to class Test2 but start making an independent copy of it??? why I can write such a code and it works:

1
2
3
4
5
6
7
8
9
10
11
int main()
{
   int *a;
   int *b;
   a= new int;
   *a = 5;
   b=a;
   *b += 1;
}
It works fine, but when I use class as argument for another class, it failes?(works only if to run AGAIN Iniate() command?)


As fat as I know, in this case "testing" should be not a data it self, but a memory adress, where this class locates. So what could be problem in?
I even tried to use "static" before declaration, but it resulted in an error:
../Libraries/libMonolith.so: undefined reference to `Monolith::tesla'
Last edited on
Please post the version where you 'use class as argument for another class'. That will help us understand your problem.
Last edited on
Here is a part of constructor(this class is some kind of programm kernel)

1
2
3
4
    Tesla *tesla;
    tesla = new Tesla; //initializing class
    
    orator = new Orator(tesla); /*initializing addon class with class as agrument. HERE, istead of taking "tesla" adress, it runs "NEW" AGAIN!!!!!*/


Here is another class
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Orator
{
	public:
		Orator(Tesla *database); //Here class constructor accepts as argument another class.
		~Orator();
		string *GetWord(string *definition);
		string *GetWord(string definition);
	private:
		void GenerateWordList();
		IceGrid *words;
		int *word_pos;
		string *language;
		Tesla *tesla;
		string *querry;
		int *column;
};

If it's better to understand, here is a "Orator"'s constructor
1
2
3
4
Orator(Tesla *database)
{
      tesla = database;
}


Here is a class, that is being given as an argument:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Tesla {

	public:
		Tesla();
		~Tesla();

		int Turbo(string query, IceGrid *grid);
		int Fellix(string query, IceGrid *grid, int start_field);
		int Injet(string query);
		int *Records;
		int *Fields;
	private:
		int GetTesla();
		int Establish();
		MYSQL *mysql;
		char *host;
		char *user;
		char *pass;
		char *database;	
};

Here is constructor for Tesla:
1
2
3
4
5
6
7
8
9
Tesla::Tesla()
{
	GetTesla();
	mysql = new MYSQL;
	mysql_init(mysql);
	Establish();
	Records = new int;
	Fields = new int;
}

I tried to move this constructor strings to separate functions, to test what a hell is going on, and why I do not win in performance nothing.... It started crashing(in class that get's tesla as agrument, tesla is NULL! without reinitializing ALL data).
then, I tried to put cout<<"Duplicated run"<<endl; in
1
2
		int GetTesla();
		int Establish();
functions. And I saw over 100! of such reruns.

So, when tesla is given as agrument to another class, it starts running new instead of using already cteated!
One more note... all this classes are built as shared libraries, that are staticaly linked(in mean in CMakeLists.txt set as link_library() ).
I tired of wondering what could be wrong. As you noticed Tesla is mysql driver. And if it always creates new copies it's terrifull waste or resources and memory.

PS. Such a fair, that Tesla *tesla reffers not to Tesla, but to new Tesla;
Last edited on
You are making false assumptions.

/*initializing addon class with class as agrument. HERE, istead of taking "tesla" adress, it runs "NEW" AGAIN!!!!!*/


^ This is false. That code you posted is not creating another Tesla. It is running new, but only to create a new Orator.

Have you checked to make sure that the program even gets to the new Orator line? What might be happening is that Tesla's ctor is creating new Teslas somehow.

Check GetTesla, Establish, and MYSQL's ctor and make extra sure none of them are creating any new Teslas (either with new, or on the stack).

EDIT: although MYSQL is probably some other lib, so you probably don't have to worry about that. Maybe just show us GetTesla and Establish.
Last edited on
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
int Tesla::GetTesla()
{
	TeslaLogin *Login;
	Login = new TeslaLogin;
	ifstream config("./.config/tesla.dat", ios::in);
	if(!config)
	  {
		cout<<"Database config file error!"<<endl;
		exit(1);
	  }
	config.read(reinterpret_cast<char *>(Login), sizeof(*Login));
	host = new char[ strlen(Login->Host) +1 ];
	strcpy(host, Login->Host);
	user = new char[ strlen(Login->User) +1 ];
	strcpy(user, Login->User);
	pass = new char[ strlen(Login->Pass) +1 ];
	strcpy(pass, Login->Pass);
	database = new char[ strlen(Login->Data) +1 ];
	strcpy(database, Login->Data);
	delete Login;
}
int Tesla::Establish()
{

if(!(mysql_real_connect(mysql, host, user, pass, database, 0, NULL, 0)))
{
	cout<<"MYSQL connection error"<<endl;
	cout<<endl;
	exit(1);
}
else
{
    mysql_set_character_set(mysql, "utf8");
}

delete [] host;
delete [] user;
delete [] pass;
delete [] database;
}


Maybe I'm an idiot, but no new teslas created here. I 100% sure say to you, that when only tesla is given as an argument, it runs it all again and again. It I cut these 2 fuctions shown abowe form constructor to any 3-rd, and make it run manually, then it works only once, and as only given as an argument = > segmentation fault. Cause it makes NEW copies and if not to allow rerun there 2 functions = > pointers remain undefined!

By the way... MYQSL - is a connector to MySQL database provided by MySQL AB company, it just cant't have any access to tesla, as far, as they couldn't know what libraries will I create based on it.
Last edited on
And by the way... if I make a wrong assumptions, then why, if in GetTesla() or Establish() I add string "cout<<"hello world"<<endl;"
I get entire page full of this text? Isn't a proof, that new, new and new teslas are created?
Nope.
Post TeslaLogin::TeslaLogin() code

If you want to count the instances of a class, use an static counter that increments in every constructor, [and decrements in the destructor].

BTW: is it necessary the dynamic allocation?
1
2
3
Records = new int;
Fields = new int;
Login = new TeslaLogin;


Edit: Do you get an stack overflow? Does the program end?
Last edited on
1) You're mistaken. TeslaLogin - is not a class. It's a simple struct, that has 4 variables for storing host, pass, database and login information.

Declaration looks like this:
1
2
3
4
5
6
struct TeslaLogin {
char login[40];
char pass[40];
char host[40];
char database[40];
};

As you see, it's a simple struct for storing data. No functions ot constructors at all.

Edit: Do you get an stack overflow? Does the program end?

No. Well, seems I explained badly my problem. Well... Imagine, I have Firefox brobser. It has module support. It would be bad, if each module for example should redowload each page you visit to work with data, isn't it? The same story here. I need only one database connection to setup per all modules and entire program.

But... It crashes after second level or I need to make constructor to recreate entire class each time in automatic mode.

Take a look... Programm starts, I connect to DB(DataBase), then, I store it as *DB type(pointer). Then, fuctions and classes are quite a lot, over 30 000 of programm code(I mean all CPP, not H files).
Then, it should work as this:
1
2
3
4
5
6
7
8
9
10
SomeClass *test1;
test1 = new SomeClass;
//THE ONLY INITIALIZATION
RunTest1(test1);

RunTest1(SomeClass *test)
{
///SOME ACTIONS HERE
RunTest2(test); ////HERE CLASS POINTER DATA IN SOME REASONS LOST
}


Hope this time I made myself clear. I need some data to initialize only once peer all program, no matter how many times and how deep this usage goes. But after second level class begins creating "new" instead of using already existing.
I dunno why are you creating those instances.
I need some data to initialize only once peer all program, no matter how many times and how deep this usage goes.

Maybe try Singleton pattern (example http://www.yolinux.com/TUTORIALS/C++Singleton.html )
Topic archived. No new replies allowed.