Instantiating a New Object in C++ - c++

I'm a Java/PHP programmer learning C++.
I've created a class called UserAccount and a class called Database.
I have an input file with five names:
Bob
Sam
Jane
Mark
Ann
I have the following (pseudo)code:
UserAccount *ua;
while (reading through the list of names, line by line) {
ua = new UserAccount(name); // Create a new user based on this name
Database->add(ua); // Add the user to the database
}
Database->listAllUsers();
The output should mirror the input file. Instead, I get:
Ann
Ann
Ann
Ann
Ann
I assume this has something to do with pointers, but I can't figure it out. I think I've provided enough information to identify the problem, but if the (pseudo)code above looks correct, I can provide more.

Could you provide an example of the correct implementation?
This would be a start:
#include <string>
#include <vector>
class UserAccount {
public:
UserAccount(const std::string& name) : d_name(name) {}
...
private:
std::string d_name;
};
class Database {
public:
Database() : d_accounts() {}
void add(const UserAccount& account) {
this->d_accounts.push_back(account);
}
...
private:
std::vector<UserAccount> d_accounts;
};
void zb() {
Database db;
db.add(UserAccount("Bob"));
...
}
It's different from what you posted because the vector's storing values of UserAccounts. At any rate -- more code would help. I'll eventually delete this because it's not a real answer(well, maybe update once the problem's defined better).

To follow up from my comments. You are likely running afoul of pointers, the std::string class will give you behaviour much more similar to that of Java.
The simplest solution will be to use the string strdup() call.
#include <cstring> // provides C string interface
UserAccount::UserAccount(char *n) {
name = strdup(n);
}
UserAccount::~UserAcount() {
// This is older C style, cleanup. Need or the memory will "leak".
free(name);
// You could also use: delete[] name;
}
Alternatively you could use std::string, but I'll leave that to your learning process. There is a lot of information on pointers out there, it will help your learning to understand pointers intimately.
// e.g.
char *str1 = "ann";
char *str2 = "bob";
str1 = str2;
// Both equal "bob".
str1 = "carol";
// Both equal "carol"!
Good luck.

In C++, unlike other languages, you must explicitly think about where things are stored in memory. A pointer tells you where to look in memory to find something. An analogy would be to tell you to look at at the third letter in the 5th row on page 124 of a book. If my book is written in pencil, I could erase the words on that page and replace them with other words, and while the pointer would stay the same (that is, I look at the same location in the book), what is being pointed to would change.
This is what is happening in your code. Each time you read in a name, you are erasing the previous name and writing the new name in the same memory location. Thus, when you pass in a pointer in your constructor, you are in danger of the memory you are pointing to changing.
To fix this, you need to make a local copy of the name. This can be done by using the string class, as in the response by #Justin. But, for teaching purposes (this code is a bit more complicated), this is how you could allocate new memory internally (the string class just does it for you):
class UserAccount {
public:
UserAccount(const char *name)
{
m_name = new char[strlen(name)+1];
strcpy(m_name, name);
}
~UserAccount()
{
delete [] m_name;
}
private:
char * m_name;
};
Note that we are now using the destructor, because we've allocated memory and need to free it again when the class is deleted. Also note that I haven't checked to see if the name being passed in is null, which should be done. A final note is that strings are implicitly null terminated to tell you when you've hit the end of the string. This is why we must allocate a large size -- to hold the null at the end of the string.
As #Marc pointed out, you can also use strdup, but I thought a longer explanation and showing the explicit allocation of memory would be useful to give a better sense of what is going on.

Menu driven program using STL & Algorithm
U need a useraccount class to store the details of an individual user and database class to store the details of all useraccount s.
use string, stl, algorithms for efficiency.
A sample menu driven program for your need:
#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
using namespace std;
class useraccount
{
string name;
//other details
public:
void get(string str)
{
name=str;
}
void display()
{
cout<<name<<endl;
}
};
void display_db(useraccount & e)
{
e.display();
}
void main()
{
vector<useraccount> database;
useraccount *ptr;
int choice;
string name;
do
{
cout<<"\n\n1.Insert \n2.Delete\n3.Display\n4.Exit \nEnter your choice: \n";
cin>>choice;
switch(choice)
{
case 1:
ptr=new useraccount;
cout<<"Enter name:\n";
cin>>name;
ptr->get(name);
database.push_back(*ptr);
break;
case 2:
database.pop_back();
break;
case 3:
for_each(database.begin(),database.end(),display_db);
break;
case 4:
cout<<"Quiting";
break;
default:
cout<<"wrong choice";
}
}while(choice!=4);
}

Related

Set and get member functions manipulation of data members

So I'm an newbie to programming and I have encountered a
case for which I suppose qualifies as an authentic question
in this awesome forum. Is there a way to write statements inside my get functions so that I can obtain all the changed data member values without having to create multiple get functions
for each data member?
Regards
I am practicing building programs which are easy to maintain by localizing the effects to a class's data members by accessing and manipulating the data members through their get and set functions. In this regard I have two data members for which I wish to change. After compiling, the set functions works well by changing the values but the get functions can only return one of the data member values at a time.
class GradeBook
{
public:
void setCourseName(string code,string name)
{
CourseCode = code;
CourseName = name;
}
string getCourseName()
{
return CourseCode;
return CourseName;
}
void displayMessage()
{
cout<<"Welcome to the GradeBook for: \n" <<getCourseName()
<<endl;
}
private:
string CourseName;
string CourseCode;
};//end class GradeBook
After compiling and running the program, the program outputs the CourseCode but the CourseName doesn't get displayed. I had to create two get functions each to obtain the two data members. I don't want to have 2 get functions to obtain the data member values. I just want to use one get function to keep the code at minimum.I wish to use one get function to return two values for each data member. I have already tried using one return statement and separated the data members with a comma.
Your idea of using return twice cannot work, the first return will return control to the caller and the second will never be executed. You should have got warning about it from your compiler.
I believe that an initial solution could be to use std::pair (docs: https://en.cppreference.com/w/cpp/utility/pair), see snippet below.
NOTE: using namespace std; (which is most likely what you are doing in the code you do not show), is a bad practice, consider using the fully qualified name
#include <string>
#include <utility>
#include <iostream>
//Bad practice, I added it only to keep differences with OP code small
using namespace std;
class GradeBook
{
public:
void setCourseName(string code,string name)
{
CourseCode = code;
CourseName = name;
}
std::pair<string, string> getCourseName()
{
return {CourseCode, CourseName};
}
void displayMessage()
{
//only in C++17
auto [code, name] = getCourseName();
cout<<"Welcome to the GradeBook for: \n" << code << " - " << name
<<endl;
}
private:
string CourseName;
string CourseCode;
};//end class GradeBook
Note that auto [code, name] is a feature called structured binding, available only in C++17, if you have an older compiler, you have to return a std::pair<std::string, std::string> and access its elements using the member variables first and second.
Now, std::pair is good for this contrived example, but, for your case, you might want to consider doing something a bit more readable, because the elements of the pair have the same type so the user of your library will have difficulties remembering what is the first and second element. So you might want to use a custom-made struct with some more meaningful names.
#include <string>
#include <utility>
#include <iostream>
//Bad practice, I added it only to keep differences with OP code small
using namespace std;
struct CourseCodeAndName{
std::string code;
std::string name;
};
class GradeBook
{
public:
void setCourseName(string code,string name)
{
CourseCode = code;
CourseName = name;
}
CourseCodeAndName getCourseName()
{
return {CourseCode, CourseName};
}
void displayMessage()
{
auto codeAndName = getCourseName();
cout<<"Welcome to the GradeBook for: \n" << codeAndName.code << " - " << codeAndName.name
<<endl;
}
private:
string CourseName;
string CourseCode;
};//end class GradeBook
See this example. Alternatively you can use std::tuple.
class GradeBook
{
/* ... */
public:
std::pair<std::string, std::string> get(){
return std::make_pair(CourseName, CourseCode);
}
};
int main()
{
GradeBook book1("Hello","World")
auto result = book1.get();
cout << result.first << result.second;
}
If you write:
return x,y;
or:
return x;
return y;
You should know that in first case you get the last value (you get y), and in second case you get the value of first return (you get x, because as soon as compiler see return, function will return the value, and then function will go in epilogue state (cleaning of stack memory assigned to function, both inline and non-inline function).
And about the use of get function it's normal. If you want to use the value to do something of logic (not to display), yes you should use a lot of get function. Instead if you want to display the values, use a void function, for example "void printData();", and inside it write code to print data. You probably setted the class variables as private (following the encapsulation rules) so you will have access to them inside the print function.

trouble making c++ student class [closed]

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
For my assignment I have to make a program to read student data from standard input, sort it by last name / first name, and print out the result to standard output. Students consists of a last name, first name, and a grade point average. It says to there are no more than 50 students.
It also says you should not rely on an external library function to do the sort.
Here is the example:
Ware Henry 87.2
Dantes Edmond 91.4
Earhart Amelia 92.6
Here is how it should be sorted:
Dantes Edmond 91.4
Earhart Amelia 92.6
Ware Henry 87.2
Here is the code I have so far that is not working properly:
#include <iostream>
#include <string>
using namespace std;
class student
{
public:
student();
void input();
void output();
void sort();
private:
string Fname;
string Lname;
float gpa;
}
student::student()
{
Fname = "";
Lname = "";
gpa = 0;
}
void student::input()
{
cout << "Enter first name, last name, and gpa"<<endl;
cin >> Fname >> Lname >> gpa;
}
void student::sort()
{
char temp;
int count = 0;
int i = 1;
while (i < word.size()) {
if (word[i - 1] > word[i]) {
temp = word[i];
word[i] = word[i + 1];
word[i + 1] = temp;
i++;
if (i >= word.size())
{
alpha(word);
}
}
else
{
count++;
}
}
return word;
}
void main()
{
student.input();
}
Any advice on where I went wrong and any possible solutions?
your student class has member variables to hold only one student, you need 50 instances of class student.
then you should hold these instances in an array/vector (whatever for container you are allowed to use) I assume you need to use a raw array so something like this will do.
student* students = new student[50];
what you then need is a compare function in your class to be able to sort the array, the compare function knows the internals of your class and you can decide how you want to sort the list e.g. after surname.
the sort function could be inside your class declared as a static function or maybe more logically an external function since student is not a container of student instances.
don't forget to delete the array when done
delete [] students;
in real world problems you would use std containers and e.g. algorithm sort for this kind of work.
Your compiler must have told you that word and alpha used in sort method are undeclared identifiers and count is assigned but never used.
Solution: Never ever steal code from wild wild web without understanding what it does. You may take others' code as inspiration, but blind copy-paste is a big no-no.
To give you a next step: you haven't even stored your students, you just input one, how would you sort just one entry? Think (and code) what you should use to store them and start working from there on how to sort them.
Good luck.
There are several reasons why your code is not working, first reason is that your class definition needs semicolon ';' at the end to close it.
class student
{
public:
student();
void input();
void output();
void sort();
private:
string Fname;
string Lname;
float gpa;
}; //semicolon here
In your sort() method the variable word is used but never declared, coding is not magic, the variable must declared and initialized before it is used like in your code.
while (i < word.size()) { //word must be declared somewhere
Also, in the sort method, you call a function alpha(word), this function does not exist in your program.
The sort method is of type void, which means it will not return anything, yet you are trying to return a string.
Another problem with the sort method is that it is never called from anywhere and will never be run.
There is also a big problem here with the way you are trying to use your class. To use the methods of the class you first have to instantiate an object of that class, you can then access the methods of the class through the object like this:
int main()
{
student theStudent;
theStudent;
theStudent.input();
return 0;
}
Another fundamental problem is that you are only going to get data for one object like this, you need to store several objects in something like an array and then sort the objects in the array:
int main()
{
student students[5];
for (int i = 0; i < 5; i++)
{
student newStudent;
students[i] = newStudent;
newStudent.input();
}
sort(students);
delete[] students;
return 0;
}
Which brings us to the sort method. It would be wise to not do the sorting as a method of the student class, but as a function called from main instead (like in the example above), that way it is easy to sort the array of student objects from main.
These are a few advice to start with, i am not going to do your complete homework for you though, if you use google and some of your precious energy, i believe that you will succeed.

How can I access an array stored in an object?

I'm quite new to C++. I've been trying to figure this out for days - there'll be an easy solution no doubt but I haven't been able to find it (after much googling)! My problem is this:
I'm trying to create a class with a member function that reads in characters from a file and stores them in an array. I want to be able to create multiple objects (not sure how many - decided by the user), each with their own arrays filled with characters taken from different files. I think I've managed to do that. How would I then go about accessing the object's array in main?
The code I'm working on is long and messy but something along these lines (char.txt contains simply '12345' in this case):
#include <iostream>
#include <fstream>
using namespace std;
class Something{
public:
void fill_array(char array_to_fill[]){
char next;
ifstream input;
input.open("chars.txt");
input.get(next);
while(!input.eof())
{
for(int i = 0; i < 6; i++)
{
array_to_fill[i] = next;
input.get(next);
}
}
}
};
int main()
{
Something* something = new Something[1];
char array_to_fill[5];
something->fill_array(array_to_fill);
//I'd like to be able to access the array here; for example - to cout the array.
return 0;
}
Apologies if a) my terminology is wrong b) my code is rubbish or c) my question is stupid/doesn't make sense. Also I should add I haven't learnt vectors yet and I'm not supposed to use them for the program I'm making. Any help would be much appreciated. Cheers!
Your class does not store the array at all. It is simply a holder for a method. You probably want something like this, where each instance of the class holds the array. (I changed it to std::string since they are nicer to work with.)
class Something
{
private:
std::string data;
public:
void fill_data( const std::string& filename )
{
ifstream file( filename );
file >> data;
file.close();
}
std::string get_data() const
{
return data;
}
}
int main()
{
std::vector<Something> my_things;
my_things.push_back( Something() );
my_things[0].fill_data( "chars.txt" );
cout << my_things[0].get_data() << std::endl;
my_things.push_back( Something() );
my_things[1].fill_data( "another_file.txt" );
cout << my_things[1].get_data() << std::endl;
}
Since you are using C++, not C, get used to writing C++ code instead of C. (std::vector instead of C arrays (for unknown length arrays), std::string instead of char*, etc).
I think your question is too general for the format of stack overflow, but what you want in this case is to either create a public member, or create a private member with setters and getters.
class Something
{
public:
std::string m_string;
}
int main()
{
Something A;
A.m_string = "toto";
cout << A.m_string;
return 0;
}
Put a string for convenience (you could use a const char* but you will have to understand what is the scope to know when it will not be accessible anymore and you are not quite there yet) and there may be typos since I typed this from a phone.
If you really want to access the chars themselves, pass a char* with a size_t for the length of the array or use std::array if possible.
Right now the method fill_array is creating a local copy of array_to_fill, so any changes that you make to array_to_fill only happen in the local method. To change this, pass by pointer. This way the pointer gets copied instead of the whole array object. I didn't test this but it should look more like this:
void fill_array(char* array_to_fill){
...
}
You don't need to change anything in the main method.
To actually access the elements you can use [] notation. I.e. cout << array_to_fill[0] in the main method.
Edit: I think that change should work.

Vector of object pointers does not seem to perform as intended in C++

I have been a follower for a long time but this is the first time I ask a question. In a nutshell, the issue is; vector<Student*> studentvector that is a vector of object pointers seems to push the student info back as student ; but when I print to see the first one in vector whether it performs as intended, I see it always updates the first record with new coming student info although there is no problem on studentvector.size() It pushes the record back to the vector as many as how many time I call addStudent(...) but it fills all vector with the information of last student. What may be done to succeed in filling vector with correct info within this frame, without using smart pointers or advanced stuff?
Sorry if I am vague on my question. You may lead me to provide what is also necessary to understand the problem. Thanks in advance.
addStudent(const string alias, const string name) throw(StudentException)
{
Student* student = new Student(alias, name)
studentvector.push_back(student);
cout << studentvector.front() << endl;
}
That is the implementation of Student;
#include "Student.h"
string *Alias;
string *Name;
Student::Student(string alias)
{
Alias = new string(alias);
}
Student::Student(string alias, string name)
{
Alias = new string(alias);
Name = new string(name);
}
Student::~Student()
{
delete Alias;
delete Name;
}
const string& Student::getAlias() const
{
return *Alias;
}
void Student::setAlias(const string& alias)
{
*Alias = alias;
}
const string& Student::getName() const
{
return *Name;
}
void Student::setName(const string& name)
{
*Name = name;
}
Consider alias is not reserved.
Doh! Here's your problem - all objects from type Student use the same global pointers:
string *Alias;
string *Name;
Make these two as members in you class
class Student
{
private:
string *Alias;
string *Name;
//..
};
EDIT:
Also, I don't think, that it's a good idea to use pointer to std::string, I'd suggest you to use like this:
class Student
{
private:
string Alias;
string Name;
//..
};
Your Student.cpp defines a single global pointer Alias and a single pointer Name. What you really want is a separate Alias and Name for each Student object. You do this by adding members to the class:
class Student {
public:
Student(const std::string& a, const std::string& n);
//...
private:
std::string Alias;
std::string Name;
};
Student::Student(const std::string& a, const std::string& n)
: Alias(a), Name(n)
{}
I may be delirious here, but are you not specifically printing out front, while pushing back?
studentvector.push_back(student);
cout << studentvector.front() << endl;
You're pushing onto the back, not the front, then printing what's in front. Of course you're not seeing front changing. You need to print back or push front. If push front isn't available, you can use insert(container.begin(), object).
You also need to move those global string variables into the class as members, so that for each instance of Student, the student has instances of Name and Alias.
Another note... you're dynamically allocating a string class. The purpose of the string class is to handle the dynamic memory of a char* string for you. There's no reason for you to use string*s in this situation, as far as I can tell from your code. string will handle the new and delete internally for you.
I agree with what everyone else has said. However, I can't reproduce the problem you say you're having. In particular, the following (rather icky) code correctly outputs two lines saying "Student(foo,bar)".
#include <iostream>
#include <vector>
#include <string>
// NOTE WELL: many things in this code are bad style and should not be imitated.
// One of them is the namespace-polluting using-directive below:
using namespace std;
struct Student {
string alias, name;
Student(string a, string n) : alias(a), name(n) {}
};
class StudentException : public exception {};
vector<Student*> studentvector;
ostream& operator<<(ostream& stream, Student* student) {
stream << "Student(" << student->alias << "," << student->name << ")";
return stream;
}
void addStudent(const string alias, const string name) throw(StudentException)
{
Student* student = new Student(alias, name);
studentvector.push_back(student);
cout << studentvector.front() << endl;
}
int main(void) {
addStudent("foo","bar");
addStudent("baz","quux");
}
It might be helpful to know how your (not-working) code diverges from the above.
A couple of remarks that conceivably might be relevant:
You aren't by any chance confusing the front and back ends of the vector somehow?
If (unlike your addStudent function) your actual code has a single Student object, and is modifying it and then pushing a pointer to it onto your vector, then of course you'll get the kind of wrong results you describe, because it'll be the same pointer every time.
std::vector::front() will return you the reference to the first element in the vector.
If you want to remove element, you need to call pop_back() which will return the element and remove from the vector.
If you have Boost then check out Boost Pointer Containers.

Cpp some basic problems

My task was as follows :
Create class Person with char*name and int age. Implement contructor using dynamic allocation of memory for variables, destructor, function init and friend function show. Then transform this class to header and cpp file and implement in other program. Ok so here's my Person class :
#include <iostream>
using namespace std;
class Person {
char* name;
int age;
public:
Person(){
int size=0;
cout << "Give length of char*" << endl;
cin >> size;
name = new char[size];
age = 0;
}
Person::~Person(){
cout << "Destroying resources" << endl;
delete [] name;
delete take_age();
}
friend void show(Person &p);
int* take_age(){
return &age;
}
char* take_name(){
return name;
}
void init(char* n, int a) {
name = n;
age = a;
}
};
void show(Person *p){
cout << "Name: " << p->take_name() << "," << "age: " << p->take_age() << endl;
}
int main(void) {
Person *p = new Person;
p->init("Mary", 25);
show(p);
system("PAUSE");
return 0;
}
And now with header/implementation part :
- do I need to introduce constructor in header/implementation files ? If yes - how?
- my show() function is a friendly function. Should I take it into account somehow ?
I already failed to return this task on my exam, but still I'd like to know how to implement it.
Solve many of your issues, by switching from char * to std::string. You'll be glad you did.
The std::string class takes care of memory allocation, and deallocation as well as copying.
If this is homework, convince your professor to use std::string for beginners and save char * for the section on pointers. Also remind your professor that the C++ langauge is different than the C language. This is one of those areas.
You don't need a * when using delete or delete[]. Just supply a pointer variable to it eg.
delete[] name;
Also, your take_age member claims to return a int* but you actually return the int member itself. You need to take the address of the member using & if you want to do that. As #Jerry has commented this is not what you want to do here.
Although some on this site apparently think it is completely acceptable, good practice (see Can a constructor return a NULL value?), you should really refrain from doing things like stream operations within the constructor of your object. Do that stream reading outside and then call the function with the results.
That is, IMHO, the first step you should take.
In a typical case, managing a pointer and block of dynamically allocated memory (such as the name in this case) is enough responsibility for one class. As such, Thomas Matthews is right: you should really use string in this case. If you're going to handle it yourself, you should still split that responsibility off into a class of its own, and embed an object of that class into your Person object. If anything, std::string already tries to do too much; you'd be better off with something that does less, not more.
Your deletes should exact match with your allocations. In this case, the only allocation is:
name = new char[size];
so the only deletion should be:
delete [] name;
As far as friend functions go, you normally want the friend declaration inside the class definition, but the function definition outside the class definition:
class Person {
// ...
friend void show(Person const &);
// ...
};
void show(Person const &p) {
// ...
}
There are other possibilities, but that's the general idea. In particular, a friend is never a member function. What you had was a declaration of one (global) function named show and a definition of a completely separate member function -- that happened to have the same name, but wasn't really the same function at all.
That shows one other point: const-correctness. You were passing the parameter as a reference to Person. Unless it's going to modify the Person object (in which case, show() seems like a poor choice of name), it should probably take a reference to a const object. The same general idea applies to take_age() -- since it only retrieves a value, it should be a const function:
int take_age() const { return age; }
I've probably already tried to cover too much, so I'll shut up for the moment...
I think you should investigate the following pieces of your code (like, what's beneath them, what happens here, etc...)
int * take_age(); // You should return plain `int` here, I assume
~Person(){
cout << "Destroying resources" << endl;
delete *[] name; // Do you understand why did you put `*` here?
delete * take_age(); // Do you understand why did you write this? What behaviour you were trying to achieve?
And, actually, so on. Only when you're done with the basic stuff, I think, you can move on to header designing questions and friend functions.
First off, kudos on trying to find the right way to implement your class, particularly after having missed the answer already.
From your description at the top, I think you may have misunderstood some of what was being asked for this assignment. First, my interpretation would be that setting the value of the name and age should take place in the init() function rather than in the constructor. As mentioned by several other posters, your constructor should simply initialize your class to a known-good state. For example,
Person() {
name = NULL;
age = 0;
}
Then in your initialization function, you can assign the values. Looking at your original init() function, it should probably be mentioned that simply assigning a pointer value (char *) to another pointer (char *) only copies the value of the pointer, not the data that it represents. Thus, for the assignment of the name value you need to calculate the size of the buffer you need, allocate the buffer, and copy the data yourself. A basic init() function would probably look like
init(const char *n, int a) {
// Calculate the required name length plus a NULL-terminator
size_t nameLen = strlen(n) + 1;
// Free any previous value.
if (name != NULL) {
delete[] name;
}
// Allocate the name buffer and copy the name into it.
name = new char[nameLen];
memcpy(name, n, nameLen);
// Store the age.
age = a;
}
Finally, in your destructor you free any resources allocated by your class, in this case the name buffer.
~Person() {
if (name != NULL) {
delete[] name;
}
}
If you have a book or something associated with your class, you may want to review the information on pointers. They can be a bit tricky but are important to learn. I suspect that is why the problem specified using char * for strings rather than the STL string class.
To your question about placing information in header and source files, it is often considered good practice to create a header file that contains the class declaration and member function prototypes and then provide the implementation of your methods in a separate source file. For some simple functions, you can provide an implementation directly in your header file.
The key when providing class member definitions in a separate source file is to provide the class name to properly scope the function (i.e., Person::). So your header file may contain a class definition like
// Header file (e.g., person.h)
class Person {
private:
char *name;
int age;
public:
Person() { name = NULL; age = 0 };
~Person() { if (name != NULL) delete[] name; }
void init(const char *n, int a);
// Other method declarations and/or definitions
};
And then in your source file
// Source file (e.g., person.cpp)
void Person::init(const char *n, int a) {
// ...
}
// Rest of method definitions
Source files that use your person class need only include the header file with your class definition.
I think your problem is with this line:
friend void(Person &p);
What is it needed for.
do I need to introduce constructor in header/implementation files ?
The constructor can be in the .h or the .cpp file. It doesn't matter. Generally if the function is short it is ok to include it in the .h file. Anything longer should go in the .cpp.
my show() function is a friendly function.
Not sure what you mean by this. friend functions exist outside the class definition. Your show function is defined inside the class so does not need to be a friend.
in addition to the previously posted answers, i've got two points of advice for you:
don't use 'friend'. some here may disagree with me, but 'friend' should really not be part of C++ anymore as it goes against what OOP stands for.
naming your methods: avoid naming your methods like 'take_name' or 'take_age'. conventionally, since those are getters, consider naming them 'getName' and 'getAge'. you end up with much more respect from developers this way.