C++ class not printing?

I'mm getting a bit confused why this isn't printing the name! I've got a human.cpp :

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

human::human(int age, human *n){
m_age=age;
name = new char[2];

human::~human() = default;

void human::printDetails(){
    std::cout <<"name is      " << name << " age is " << m_age << std::endl;
}

and human.h:

class human {
    public: //: needed
        human(int age, human *name);
        ~human();
        void printDetails();
    private :
        char *name;
        int m_age;

};

and finally the main.cpp:

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

int main()

{
    human *Alex = new human(10, Alex); //pointer // needs argument //should have both age and name
    Alex->printDetails(); //print not Print

    }

So my issue is: it prints the age, but does not print the name? Any suggestions? Thanks :)

4 answers

  • answered 2018-11-08 08:36 Emadpres

    I guess you're confused with the second parameter of the human constructor. Look at this changes:

    human.h

    class human {
    public:
        human(int age, char *name);
        human(const human& h);
        human& operator=(const human& h);
        void printDetails();
        virtual ~human();
    private:
        int age;
        char *name;
    };
    

    human.cpp

    human::human(int _age, char *_name) {
        age = _age;
        name = new char[strlen(_name)+1];
        strcpy(name, _name);
    }
    
    human::human(const human& _h) { //Copy constructor
        age = _h.age;
        name = new char[strlen(_h.name)+1];
        strcpy(name, _h.name);
    }
    
    human& human::operator=(const human& _h) { //Copy assignment operator
        age = _h.age;
        name = new char[strlen(_h.name)+1];
        strcpy(name, _h.name);
    }
    
    void human::printDetails(){
        std::cout <<"name is " << name << " age is " << age << std::endl;
    }
    
    human::~human() { //Destructor
        delete[] name;
    }
    

    main.cpp

    int main() {
    
        human *alex = new human(10, "Alex");
        alex->printDetails();
    
        human *anotherAlex = new human(*alex);
        anotherAlex->printDetails();
    
        delete alex;
        delete anotherAlex;
    }
    

    A suggestions: I would use Human as the class names and alex for the variable names. (See how I capitalized them)

  • answered 2018-11-08 08:40 Swordfish

    There is no need for any new in your code. Since you #included <string> in your code I assume you want to use it:

    #include <string>
    #include <iostream>
    
    class Person
    {
        int age;
        std::string name;
    
    public:
        Person(int age, std::string name)
        : age  {  age },
          name { name }
        {}
    
        int get_age() const { return age; }
        std::string const& get_name() const { return name; }
    
        void print_details() const {
            std::cout << "My name is " << name << ". I am " << age << " years old.\n";
        }
    };
    
    int main()
    {
        Person p{ 19, "Alex" };
        p.print_details();
    }
    

    If you *really* want to do it the hard waytm:

    #include <cstring>  // std::strlen()
    #include <utility>  // std::exchange(), std::swap()
    #include <iostream>
    
    class Person
    {
        char *name_;
        int   age_;
    
    public:
        Person(int age, char const *name)  // constructor
                           // we don't want to call std::strlen() on a nullptr
                           // instead allocate just one char and set it '\0'.
        : name_ { new char[name ? std::strlen(name) + 1 : 1]{} },
          age_  { age }
        {
            if (name)
                std::strcpy(name_, name);
        }
    
        Person(Person const &other)  // copy-constructor
        : name_ { new char[std::strlen(other.name_) + 1] },
          age_  { other.age_ }
        {
            std::strcpy(name_, other.name_);
        }
    
        Person(Person &&other) noexcept  // move-constructor
        : name_ { std::exchange(other.name_, nullptr) },  // since other will be
          age_  { other.age_ }                            // wasted anyway, we
        {}                                                // "steal" its resource
    
        Person& operator=(Person other) noexcept  // copy-assignment operator
        {                                   // since the parameter other got
            std::swap(name_, other.name_);  // copied and will be destructed
            age_ = other.age_;              // at the end of the function we
            return *this;                   // can simply swap  the pointers
        }                                   // - know as the copy&swap idiom.
    
        ~Person() { delete[] name_; }  // destructor
    
        void print_details() const
        {
            std::cout << "I am " << name_ << ". I am " << age_ << " years old.\n";
        }
    };
    
    int main()
    {
        Person p{ 19, "Alex" };
        p.print_details();
    }
    

    If you don't want to implement the special member functions you'd have to = delete; them so the compiler-generated versions - which won't work correctly for classes managing their own resources - won't get called by accident.

  • answered 2018-11-08 08:43 break1

    For beginner you may use std::string, so you already included it. ))

    human.h

    #include <string>
    class human
    {
        public: //: needed
            human(int age, std::string name);
            void printDetails();
        private :
            std::string name;
            int m_age;
    };
    

    human.cpp

    #include <iostream>
    #include "human.h"
    
    human::human(int age, std::string n)
    {
        m_age = age;
        name = n;
    }
    
    void human::printDetails()
    {
        std::cout <<"name is: " << name << " age is: " << m_age << std::endl;
    }
    

    main.cpp

    #include "human.h"
    
    int main()
    
    {
        human *Alex = new human(10, "Alex");
        Alex->printDetails();
    
    }
    

  • answered 2018-11-08 08:53 Roshan Mehta

        #include <iostream>
        #include <cstring>
        #include <new>
    
        using namespace std;
    
        class human {
            public: 
                human(int age, const char * name)
                {
                    m_age=age;
                    m_name = new char[strlen(name)+1];
                    strcpy(m_name,name);
                }
                ~human()
    {
    delete[] m_name;
    }
                void printDetails()
                {
                    std::cout <<"name is      " << m_name << " age is " << m_age << std::endl;
                }
            private :
                char *m_name;
                int m_age;
    
        };
    
        int main()
        {
    
            human *Alex = new human(10, "alex"); //pointer // needs argument //should have both age and name
            Alex->printDetails(); //print not Print
            delete Alex;
            return 0;
        }
    

    You need to read more. The example you shared was wrong at many level, also read about dynamic memory management.