Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
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 :)
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.
#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.
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);
return *this;
}
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)
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();
}
Related
Hello I didn't use C++ for years now, so I'm kinda rusty and can't figure this out!
I have this code | person.h
#ifndef PERSON_H
#define PERSON_H
#include<string>
class Person {
private:
std::string fName, lName;
int age;
enum professionEnum {
Barber,
Developer,
Marketer
} profession;
public:
Person();
Person(std::string fName, std::string lName, int profession);
void setFName(std::string fName);
void print();
};
#endif
a simple person class.
What I want to do is for my constructor Person() to take an int, example :
Person me = Person("me", "meow", 0); // This should assign "me" to Barber, enum index is 0.
Here is what I tried so far (all errors):
this->profession = professionEnum::profession;
this->profession = 0;
this->profession = professionEnum(profession);
Here is the full person.cpp code
#include "person.h"
#include <iostream>
Person::Person() {
this->age = 18;
this->fName = "Default";
this->lName = "Default";
}
Person::Person(std::string fName, std::string lName, int profession) {
this->fName = fName;
this->lName = lName;
this->profession = professionEnum::profession;
this->profession = 0;
this->profession = professionEnum(profession);
}
void Person::print() {
std::cout << "Age : " << this->age << ", FName : " << this->fName << ", LName : " << this->lName << std::endl;
}
Thanks for your help
PS: If you spot any bad practices / bad code, please tell me.
I've recently begun learning C++ and I'm having some trouble updating a pointer in my Movie class. I've got a feeling I have an issue somewhere in my Move/Copy constructors but have been trying to solve this issue for hours, swapping pointers to references to values and finally coming here for help.
I have a class Movie, which contains a string name, string rating and int watched member variables. Another class Movies, holds a vector of the movies. On movie, my method increment_watched is supposed to increment the int watched by one, the value does get incremented but it seems like the value is not saved. The display_all_movies method in Movies, which simply displays the movies that it stores holds the old value for watched. I know the issue is probably something really small but I haven't been able to work out why the value isn't being saved.
If someone could explain why the pointer value seems to be getting overridden I'd appreciate it greatly. Thanks in advance!
Code is below, there is some debug couts in there.
Movie.h
#ifndef _MOVIE_H_
#define _MOVIE_H_
#include <string>
#include <iostream>
class Movie {
private:
std::string *name;
std::string *rating;
int *watched;
public:
std::string get_name();
std::string get_rating();
int get_watched();
void increment_watched();
Movie(std::string name, std::string rating, int watched_val); // normal constructor
Movie(const Movie &source); // copy constructor
Movie(Movie &&source); // move constructor
~Movie();
};
#endif // _MOVIE_H_
Movie.cpp
#include "Movie.h"
std::string Movie::get_name() {
return *name;
}
std::string Movie::get_rating() {
return *rating;
}
int Movie::get_watched() {
return *watched;
}
void Movie::increment_watched() {
std::cout << *watched << std::endl;
(*watched)++; // TODO FIX!
std::cout << *watched << std::endl;
}
Movie::Movie(std::string name, std::string rating, int watched_val)
: name{nullptr}, rating{nullptr}, watched{nullptr}{
std::cout << "Creating movie " << watched_val << " with normal constructor" << std::endl;
this->name = new std::string{name};
this->rating = new std::string{rating};
this->watched = new int{watched_val};
}
Movie::Movie(const Movie &source)
: Movie(*source.name, *source.rating, *source.watched) {
std::cout << "Creating movie " << *source.watched << " with copy constructor" << std::endl;
}
Movie::Movie(Movie &&source)
: Movie(*source.name, *source.rating, *source.watched) {
std::cout << "Creating movie " << *source.watched << " with move constructor" << std::endl;
source.name = nullptr;
source.rating = nullptr;
source.watched = nullptr;
}
Movie::~Movie() {
delete name;
delete rating;
delete watched;
}
Movies.h
#ifndef _MOVIES_H_
#define _MOVIES_H_
#include <vector>
#include <string>
#include <iostream>
#include "Movie.h"
class Movies {
private:
static int count;
std::vector<Movie> *movies;
public:
void add_movie(std::string &&name, std::string &&rating, int &&watch);
void increment_movie_count(std::string &&name);
void display_all_movies();
void count_movies();
Movies();
Movies(const Movie &source); // copy constructor
Movies(Movie &&source); // move constructor
~Movies();
};
#endif // _MOVIES_H_
Movies.cpp
#include "Movies.h"
int Movies::count = 0;
void Movies::add_movie(std::string &&name, std::string &&rating, int &&watch) {
bool contains {false};
for(auto movie : *movies) {
if(movie.get_name() == name) {
contains = true;
}
}
if(!contains) {
movies->push_back(Movie{name, rating, watch});
count++;
}
}
void Movies::increment_movie_count(std::string &&name) {
for(auto movie : *movies) {
if(movie.get_name() == name) {
movie.increment_watched();
}
}
}
void Movies::display_all_movies() {
for(auto movie : *movies) {
std::cout << "Title " << movie.get_name() << " Rating " << movie.get_rating() << " Watched " << movie.get_watched() << std::endl;
}
}
void Movies::count_movies() {
std::cout << "There are " << count << " movies " << std::endl;
}
Movies::Movies() {
movies = new std::vector<Movie>{};
}
Movies::~Movies() {
delete movies;
}
And finally main.cpp
#include <iostream>
#include "Movies.h"
using std::cout;
using std::endl;
int main() {
Movies *my_movies;
my_movies = new Movies();
(*my_movies).count_movies();
my_movies->add_movie("Big", "PG-13", 2);
my_movies->increment_movie_count("Big");
my_movies->display_all_movies();
return 0;
}
Changefor(auto movie : *movies) to for(auto& movie : *movies) to update the original movie objects. Otherwise, you're only updating copies of the movie objects.
When putting freeSeats to 0, my code still says that a person has avalibale seats in his/hers car.
I have created two classes. One for Car and one for Person. The Car class has a function to see if there are free seats in the car. A person-object can have a car. When checking if the person has avalibale seats, my code responds "Yes" even though I give input "0". Why?
#pragma once
#include <iostream>
//Here is class Car declaration
class Car {
private:
unsigned int freeSeats;
public:
bool hasFreeSeats() const;
void reserveFreeSeat();
Car( unsigned int freeSeats);
};
//Here is function definition
#include "Car.h"
bool Car::hasFreeSeats() const {
if (freeSeats > 0)
return true;
return false;
}
void Car::reserveFreeSeat() {
--freeSeats;
}
Car::Car(unsigned int freeSeas) :
freeSeats{ freeSeats }
{
}
//Here is class Person declaration
class Person {
private:
std::string name;
std::string email;
Car *car; //pointer to a car
public:
Person(std::string name, std::string email, Car *car = nullptr);
std::string getName() const;
std::string getEmail() const;
void setEmail();
bool hasAvalibaleSeats() const;
friend std::ostream& operator << (std::ostream& os, const Person& p);
};
//Here is function definition
Person::Person(std::string name, std::string email, Car *car) :
name{ name }, email{ email }, car{ car }
{
}
std::string Person::getName() const {
return name;
}
std::string Person::getEmail() const {
return email;
}
void Person::setEmail() {
std::string newEmail;
std::cout << "What is the e-mail adress?";
std::cin >> newEmail;
email = newEmail;
std::cout << "E-mail has been set." << std::endl;
}
bool Person::hasAvalibaleSeats() const {
if (car != nullptr) { //check if there is a car
return car->hasFreeSeats();
}
return false;
}
std::ostream& operator << (std::ostream& os, const Person& p) {
std::string seats = "No";
if (p.hasAvalibaleSeats())
seats = "Yes";
return os << "Name: " << p.name << "\nE-mail: " << p.email << "\nHas free seats: " << seats << std::endl;
}
//From main im calling
#include "Car.h"
#include "Person.h"
int main() {
Car ferrari{ 2 };
Car bugatti{ 3 };
Car jeep{0};
Person one{ "Aleksander","aleks#aleks.com", &ferrari };
Person two{ "Sara","sara#sara.com", &bugatti };
Person three{ "Daniel", "daniel#daniel.com", &jeep };
Person four{ "Chris", "chris#chris.com" };
std::cout << one << std::endl;
std::cout << two << std::endl;
std::cout << three << std::endl;
std::cout << four << std::endl;
system("pause");
return 0;
}
I get
Name: Aleksander
E-mail: aleks#aleks.com
Has free seats: Yes
Name: Sara
E-mail: sara#sara.com
Has free seats: Yes
Name: Daniel
E-mail: daniel#daniel.com
Has free seats: Yes
Name: Chris
E-mail: chris#chris.com
Has free seats: No
But I want Daniel has free seats to be "No"
There's a typo here:
Car::Car(unsigned int freeSeas) :
freeSeats{ freeSeats }
{}
You wrote freeSeas instead of freeSeats. Due to that, the freeSeas parameter is unused and freeSeats{ freeSeats } does nothing as freeSeats is refering to the member variable, not the parameter.
Debugging is way easier when you enable compiler warnings. Compiler is your friend, and will help you immensely if you are willing to hear it.
For example, gcc gave me the following warnings when compiling your code:
prog.cc: In constructor 'Car::Car(unsigned int)':
prog.cc:37:23: warning: unused parameter 'freeSeas' [-Wunused-parameter]
Car::Car(unsigned int freeSeas) :
~~~~~~~~~~~~~^~~~~~~~
prog.cc: In constructor 'Car::Car(unsigned int)':
prog.cc:38:16: warning: '*<unknown>.Car::freeSeats' is used uninitialized in this function [-Wuninitialized]
freeSeats{ freeSeats }
^~~~~~~~~
I don't have to understand everything, but it tells me 2 things:
There is unused argument (why? it is used to initialize...)
Variable is initialized with uninitialized value (why?)
It made me look closer at this constructor and then you can see the typo.
I am learning how to work with objects but am stuck the closest answer is could find was Read class objects from file c++.
In this question:
How would you go about the same task if your member variables were declared as private?
Try something similar to this:
Content of person.txt
John California 3683893
Stalin Russia 489895
Sample code:
#include<iostream>
#include <fstream>
#include <vector>
#include <string>
class person
{
private:
std::string _name;
std::string _address;
unsigned int _phone;
public:
person(const std::string& name, const std::string& address, unsigned int phone)
:_name(name),_address(address),_phone(phone)
{}
std::string getName() const { return _name; }
std::string getAddress() const { return _address; }
unsigned int getPhone() { return _phone; }
};
int main()
{
std::vector<person> persons;
std::string name;
std::string address;
unsigned int phone;
std::ifstream fs;
fs.open("person.txt");
if (fs.is_open()) {
while (std::getline(fs, name, ' ') && std::getline(fs, address, ' ') &&
(fs >> phone))
{
persons.push_back(person(name,address,phone));
}
}
for (auto p : persons) {
std::cout << p.getName() << " " << p.getAddress() << " " << p.getPhone() << '\n';
}
return 0;
}
Pardon the example but in this case:
#include <iostream>
#include <string>
using namespace std;
class A {
private:
string theName;
int theAge;
public:
A() : theName(""), theAge(0) { }
A(string name, int age) : theName(name), theAge(age) { }
};
class B {
private:
A theArray[1];
public:
void set(const A value) {theArray[0] = value; }
A get() const { return theArray[0]; }
};
int main()
{
A man("Bob", 25);
B manPlace;
manPlace.set(man);
cout << manPlace.get();
return 0;
}
Is it possible for me to retrieve the contents of the "man" object in main when I call manPlace.get()? My intention is to print both the name (Bob) and the age (25) when I call manPlace.get(). I want to store an object within an array within another class and I can retrieve the contents of said array within the main.
You need to define a ostream::operator<< on your A class to accomplish that - otherwise the format how age and name should be generated as text-output is undefined (and they are private members of your A class).
Take a look at the reference for ostream::operator<<. For your A class, such a operator could be defined like this:
std::ostream& operator<< (std::ostream &out, A &a) {
out << "Name: " << a.theName << std::endl;
out << "Age: " << a.theAge << std::endl;
return out;
}
Which would output something like:
Name: XX
Age: YY
So your complete code would be:
#include <iostream>
#include <string>
using namespace std;
class A {
private:
string theName;
int theAge;
public:
A() : theName(""), theAge(0) { }
A(string name, int age) : theName(name), theAge(age) { }
friend std::ostream& operator<< (std::ostream &out, A &a) {
out << "Name: " << a.theName << std::endl;
out << "Age: " << a.theAge << std::endl;
return out;
}
};
class B {
private:
A theArray[1];
public:
void set(const A value) { theArray[0] = value; }
A get() const { return theArray[0]; }
};
int main()
{
A man("Bob", 25);
B manPlace;
manPlace.set(man);
cout << manPlace.get();
return 0;
}
which will output:
Name: Bob
Age: 25