21

I'm new to c++ and I'm having difficulties with constructor and classes. So, here is my header file:

#pragma once
#include <string>
using namespace std;
class test
{

    private:
    string name;
    int number;

public:

    test();
    test(string i,int b);
};

This is cpp file:

#include "test.h"
#include <string>
using namespace std;


test::test(){}

test::test(string i,int b){
    this->name=i;
    this->number=b;
}

now, when I try to call

test t=new test("rrr",8);

I get:

1   IntelliSense: no suitable constructor exists to convert from "test *" to "test" 

So, whats the thing with classes having * in their name ( for instance, classes without .cpp file don't have asterix, all others do)? And what do I do wrong?

Kiril Kirov
  • 37,467
  • 22
  • 115
  • 187
klo
  • 414
  • 2
  • 6
  • 14

6 Answers6

53

I imagine you're coming from a Java/C# background. t is not a reference type here, it's a value type. new returns a pointer to an object. So you need any of the following:

test t = test("rrr", 8);
test t("rrr", 8);
test *t = new test("rrr", 8);

If you're not yet familiar with pointers, then definitely don't use the last one! But understanding the semantics of pointers is fairly critical; I recommend reading the relevant chapter(s) in your textbook...

Oliver Charlesworth
  • 267,707
  • 33
  • 569
  • 680
  • Nice, your answer is much better than mine :) +1 – Kiril Kirov Mar 26 '13 at 13:01
  • tnx a lot. u guessed right, i did programming in java and c# so im i bit struggling with c++ :) .... – klo Mar 26 '13 at 13:08
  • @klo If you try to program C++ like you programmed Java you will make loads of mistakes. They are not very similar at all. – john Mar 26 '13 at 13:26
  • 2
    "I imagine you're coming from a Java" that hurted but thanks anyways lol, i was missing the * operator before my variable name – LuisDev99 Dec 06 '19 at 16:57
12

So, whats the thing with classes having "*" in their name ( for instance, classes without .cpp file dont have asterix, all others do)???

You definitely need to learn about pointers. test * and test are two completely different types in C++. Here's two variables with those types:

test t;
test* p;

Here, t has type test, and p as type test*. We describe test* as "pointer to test".

You can often think of a pointer as being the memory address of an object. So in p, since it is a pointer, we could store the memory address of t, which is a test. To get the address of an object, we use the unary & operator, like so:

test t;
test* p = &t;

Note that t is a test object. You didn't need to say new test(). This is where C++ differs from other languages that you might have used, like C# and Java. In the above C++ code, t is a test object.

However, you can create objects with new test(), so what's the difference?

test t; creates a test object with automatic storage duration. This means it is destroyed at the end of its scope (often the function is being declared within).

new test() creates a test object with dynamic storage duration. This means you have to destroy the object manually, otherwise you'll have a memory leak. This expression returns a pointer and so you can initialise a pointer object with it:

test* p = new test();

So now let's look at your problem:

test t=new test("rrr",8);

We now know that new test("rrr", 8) returns a pointer to test (a test*). However, you're trying to assign it to a test object. You simply can't do this. One of them is an address and the other is a test. Hence the compiler says "no suitable constructor exists to convert from test * to test." Makes sense now, doesn't it?

Instead, you should prefer to use automatic storage duration. Only use new if you really really need to. So just do:

test t("rrr", 8);
Joseph Mansfield
  • 108,238
  • 20
  • 242
  • 324
1
test t=new test("rrr",8);

must be

//  v
test* t=new test("rrr",8);

So, whats the thing with classes having "*" in their name

* is used to indicate a pointer, it's not in the name of the class. But it's a big topic, so you should do some reseach on this.

Kiril Kirov
  • 37,467
  • 22
  • 115
  • 187
1
T* t = new T;
//     ^^^

When new is used in this object construction, it denotes the creation of a pointer. What are doing is dynamically allocating memory which I'm sure you didn't mean to do. The Rather, typical stack allocated object construction is done simply like this:

T t;

Even if you had intended on creating a pointer and allocating the memory, you did it the wrong way. A pointer is created with the * symbol, which you lacked in your code. Secondly, when you're done using the memory you created, you must remember to delete/delete[] your code. delete[] is used on dynamically allocated arrays. So this is how it would look for your pointer:

delete t;
David G
  • 94,763
  • 41
  • 167
  • 253
1

* is not part of the name, it's a modifier denoting, that the object is a pointer. A pointer is a variable holding address to some place in memory, where the actual object is stored. Some basics:

int i = 5;
int * pI = &i;

int * pI means, that you want to declare a pointer to place in memory, where an int is held. &i means, that you want to retrieve a pointer to variable. So now pI holds address in memory, where i is stored. Now you can dereference a pointer - get to value of the pointer:

int j = *pI;

Now you tell the compiler, that it should go to the address pointed to by pI and retreive its contents (since pI is a pointer to int, compiler will assume, that there's an int there).

Now, back to your example. new operator allocates memory dynamically for an object, so:

new test("rrr", 8);

results in allocating a memory for test class, calling its constructor with parameters "rrr" and 8 and returning a pointer to allocated memory. That's why you cannot assign it to test variable: new operator in this case returns a test *.

Try this code:

test * t = new test("rrr", 8);
Spook
  • 25,318
  • 18
  • 90
  • 167
0

You did not define t as a pointer:

test* t=new test("rrr",8);

Or just

test t = test("rrr",8);
bash.d
  • 13,029
  • 3
  • 29
  • 42