0

I made this class

class Person {

public:

    Person(const std::string& name, const std::string& email, const std::string& city) 
    : name(name), email(email), city(city) {
    }

    bool hasCity() const {
        return city.compare("") == 0;
    }

    void print() const {
        std::cout << name + " <" + email + ">";
        if(hasCity()){
            std::cout << ", " + city;
        }
        std::cout << std::endl;
    }

    bool equalTo(const Person& comparedPerson) const {
        return email.compare(comparedPerson.email) != 0;
    }

    bool equalId(std::string comparedId){
        return email.compare(comparedId) != 0;
    }

    const std::string name;
    const std::string email;
    const std::string city;
};

What is problematic for me is that when i try to create new Person with:

const Person& newPerson = (const Person &) new Person(name, email, city);

i get this error

error: invalid cast of an rvalue expression of type 'Person*' to type 'const Person&'
     const Person& newPerson = (const Person &) new Person(name, email, city);

I would like why newly created Person is Person* instead of just Person.

πάντα ῥεῖ
  • 1
  • 13
  • 116
  • 190
Tibor Bujdoš
  • 205
  • 2
  • 6

2 Answers2

9

new returns a pointer to object, not an object. Person* instead of Person. Really though, since you tagged this as C++14, you shouldn't be using raw pointers with dynamic allocation.

Just create a variable with automatic storage duration:

Person newPerson(name, email, city);

Or, if you need a pointer, use std::unique_ptr or std::shared_ptr which handles memory management for you:

#include <memory>
auto ptr = std::make_unique<Person>(name, email, city);
Hatted Rooster
  • 35,759
  • 6
  • 62
  • 122
2

There are two mayor ways to create a "Person" in C++. (or this is better called: instantiate an object )

One would be simply use objects with automatic storage duration. You can create it like this.

Person p(name, email, city);

You can also create references and pointers to the object:

Person* pP = &p;
Person& rP = p;

But be aware: This object will now be deleted when you leave the current scope and all references and pointers to it will become invalid.

Another way is to allocate objects with dynamic storage duration by using dynamic memory allocation.

The simple way is using new.

Person* p = new P(name, email, city); 

though when you manually create raw pointers with new you have to manually delete them somewhere

delete p;

A better solution for dynamic memory allocated objects are smart-pointers. Those would be shared/unique pointer. They remove the need to manually delete these objects. You can create those like this.

auto p = std::make_shared<Person>(name, email, city);

or use make_unique for unique pointers.

They at first seem like normal pointers but have some mechanisms behind them which makes using them more safer. For details on those you should read up on shared and unique pointers and their difference.

Hayt
  • 5,210
  • 30
  • 37
  • Please try not to spread the antiquated and inaccurate "stack vs heap"! – Lightness Races in Orbit Oct 10 '16 at 12:36
  • @LightnessRacesinOrbit do you care to elaborate this? I mean i have no "vs" in here which discusses advantages/disadvantages. Just mentioning these 2 types because I often see like people from e.g. java come over and defaulting to "new" just not knowing that you can declare local variables. So I thought I just mention there is another way. And I wanted to give them names stack/heap seemed accurate here. – Hayt Oct 10 '16 at 12:40
  • http://stackoverflow.com/a/4687324/560648 http://stackoverflow.com/a/14172583/560648 http://stackoverflow.com/q/6524888/560648 – Lightness Races in Orbit Oct 10 '16 at 13:44
  • @LightnessRacesinOrbit oh. thank you. so i seemed to use "old" vocabulary here for these things. I changed it to the appropriate names. :) – Hayt Oct 10 '16 at 13:51