Ok, so I've decided to read a little c++ now and then, just to get a basic understanding of the syntax. I am familiar with Java, and a little bit of Python. I have 'read' through a c++ for dummies book, and I thought I had the grip - until I tried to create the simplest class.
The idea was very simple: a class (named ape) takes one parameter, an int, which is stored as a private field. It has one other function, a return function, which returns the field. The main() creates an instance, and calls the method to print out the variable.
The idea was to use a string instead of an int, but I couldn't get it working, so I decided to use an int instead, which, obviously, wasn't working either.
If it is to any interest I use Code::blocks, Windows 7 and the g++ compiler.
Here are the classes:
Main.cpp
#include <iostream>
#include "ape.h"
using namespace std;
int main()
{
ape asd(10);
cout << asd.getNumber();
}
ape.h
#ifndef APE_H
#define APE_H
class ape
{
public:
ape(int num);
virtual ~ape();
int getNumber();
protected:
private:
int number;
};
#endif // APE_H
and ape.cpp
#include "ape.h"
using namespace std;
ape::ape(int num)
{
tall = num;
}
ape::~ape()
{
//dtor
}
int getNumber()
{
return number;
}
The error messages I get seems very random to me, as they are changing completely with every single change I make, and are not very self explaining. I can see how I sound like an arrogant fool, and that this whole mess is the compilers fault, but I really don't see any connection between the error messages and what's wrong in my code.
Take it easy on me, first time here. :)
I guess I should probably add the error message:
undefined reference to 'ape::ape(int)'
Not much to say without the actual error messages, but at least here is a problem:
int getNumber()
{
return number;
}
This should be int ape::getNumber(). Also in your code there is no definition for tall, should perhaps be number instead?
You are assigning a value to a variable that doesn't exist.
Change:
ape::ape(int num)
{
tall = num;
}
To:
ape::ape(int num) :
number(num)
{
}
Moreover, I don't know why you wrote a destructor, and why you decided to make it virtual. By default, the compiler will generate an empty destructor (similar to yours, but not virtual). If you don't intend to do polymorphism (with inheritance and all that "stuff"), you may delete this destructor from your code as it only brings complexity for no gain.
You also need to prefix your method definitions with the name of the class:
int ape::getNumber() // Note the "ape::" here
{
return number;
}
One last thing:
You problably want to change also your main:
int main()
{
ape asd(10);
cout << asd.getNumber() << endl;
}
Something put into cout only gets printed when one outputs endl or flush as the stream is buffered.
Regarding your last edit:
I guess I should probably add the error message: undefined reference
to 'ape::ape(int)'
You probably failed to link with ape.o. In your compilation folder, you should have your source files and a .o for every .cpp. You have to link those object files together to build your program. This message indicates that the linker is unable to find the definition for ape::ape(int). That is he was probably not given the ape.o file.
Long story short, here is what your compilation commands should look like (using g++):
g++ -o main.o -c main.cpp
g++ -o ape.o -c ape.cpp
g++ -o program main.o ape.o
You are using undeclared field "tall". Seems like your constructor should be:
ape::ape(int num)
{
number = num;
}
ape::ape(int num)
{
tall = num;
}
tall? Where did tall come from? The member was declared as number.
Better would be
ape::ape(int num) { number = num; }
Much better would be
ape::ape(int num) : number(num) { }
You need to set variable number in constructor, before you can read it in getNumber.
Try this:
ape::ape(int num)
{
number = num;
}
What is tall? The private field is called number in your example, so this function:
ape::ape(int num)
{
tall = num;
}
should be:
ape::ape(int num)
{
number = num;
}
However, in C++ you should use initialization and not assignments. While for an int is not a big deal, for more complex objects assignment is more expensive as you are copying the object, while with initialization you can use the copy constructor. Therefore the convention is to initialize all variables before the body of the constructor.
ape::ape(int num)
: number(num)
{
}
And, please declare getNumber() as a const method. Here you have a nice guide explaining all the const variants: http://developer.kde.org/~wheeler/cpp-pitfalls.html
While you are at it, add the missing class prefix, which you need if you are defining the method outside of the declaration of the class:
int ape::getNumber() const
{
return number;
}
As a last comment, I recommend you look for a convention on naming member variables. Typical are mNumber or _number. Makes reading your own code easier later on.
Related
I am new to C++, and was wondering what I am doing wrong.
I am trying to create a text-based adventure game that keeps track of player stats using an add or remove function. Currently, my function does not add five points to trust and I am trying to get it to.
#include "function.h"
using namespace std;
int main() {
double trust=100;
editPlayer user(100);
//asks user choice
cin >> firstChoice;
if (firstChoice == 1) {
user.addTrust(trust);
cout << trust;
Here is my function.cpp only using trust as an example:
#include "function.h"
editPlayer::editPlayer(double trust) {
}
void editPlayer::addTrust(double trust){
trust +=5;
}
void editPlayer::removeTrust(double trust){
trust -=5;
}
And here is my function.h:
#include<iostream>
#include<string>
using namespace std;
class editPlayer{
public:
editPlayer(double trust);
void addTrust(double);
void removeTrust(double);
};
Lets take your addTrust function:
void editPlayer::addTrust(double trust) {
trust += 5;
}
This will modify the local variable trust, and then the function will end. When the function ends, the life-time of the local variable trust also ends, and the modifications you made to it will be lost.
If you truly want to modify the argument, you need to either pass it by reference:
void editPlayer::addTrust(double& trust) {
trust += 5;
}
Or return the new value:
double editPlayer::addTrust(double trust) {
return trust + 5;
}
If you return the new value, you need to assign to it when calling the function:
trust = user.addTrust(trust);
With the above said, the code and the editPlayer class doesn't make much sense. There's just no need for a class editUser really. Possibly addTrust could be a non-member function, or maybe not a function at all.
The class name doesn't make sense, since it doesn't "edit" anything. And passing an argument to the constructor also doesn't make sense since the objects doesn't have any internal state (the value passed to the constructor is just discarded).
Currently you're not storing anything specific on behalf of user object (an object of the editPlayer class.
The cout << trust; statement just prints a value of the trust local variable which you declared at the beginning: double trust=100;. Because this variable hasn't been changed anyhow since that initialization it is still equal to 100 and this is what you see.
In order to track any editPlayer-specific information the best idea is to store that information as a data member of the class editPlayer. You can declare a data member representing the trust of an object like this:
class editPlayer{
public:
editPlayer(double trust);
void addTrust(double);
void removeTrust(double);
double getTrust() const; // add also this one, will be useful
private:
double m_trust {0}; // <---- here - a data member, aka. a class field
};
Now you must refine you constructor to let it utilize the parameter which it takes and assign its value to this new data member (because currently the constructor does nothing):
editPlayer::editPlayer(double trust) {
m_trust = trust;
}
Now in the member functions that you already have just rename the variable so that it reflects the trust data member (and not the parameter) which effectively will allow to update its value:
void editPlayer::addTrust(double trust) {
m_trust += 5;
}
void editPlayer::removeTrust(double trust) {
m_trust -= 5;
}
double editPlayer::getTrust() const { // add definition of our "getter"
return m_trust;
}
Finally you can replace that cout << trust; which we already discussed (still prints the local variable's value) with an invokation of the getter which yields m_trust's value:
cout << user.getTrust();
and see the actual effect of performing the addTrust() operation as well as get delighted with your legitimate object-oriented program.
In general the code you are asking can be covered by classes, member declarations and also a pinch of object oriented programming.
The internet has lots of good (and less than good) tutorials if you search for it.
I would try my luck with some of the following searches
CPP + classes
CPP + member declarations
CPP + dynamic vs. static memory allocation (pointers and stuff)
object oriented programming (OOP)
The examples on this site provide good (and short :D) examples of alot of basic concepts imho.
https://www.tutorialspoint.com/cplusplus/cpp_classes_objects.htm
Some of the topics also apply to other languages.
The first block with my comments:
#include "function.h"
using namespace std; // dont get into the habbit of using namespace std;
// the above can potentially open up for bugs
int main()
{
double trust=100; // This variable is declared in this scope({ ... })
// and will get deallocated once the scope ends with the character '}'
editPlayer user(100); // instance of editPlayer named 'user' is constructed
//asks user choice
cin >> firstChoice;
if (firstChoice == 1) {
user.addTrust(trust); // calling function on user object
cout << trust;
}
Now looking at the .h file i would advocate against including headers that you dont use in the header.
For small projects it does not matter at all - but for big projects of thousands lines of code removing unused includes can speed up things.
Some would prefer forward declarations - which you can look into once you are more comfortable with the basics of cpp.
#include<iostream> // not used here
#include<string> // not used
using namespace std; // disaster waiting to happen
class editPlayer{
public:
editPlayer(double trust);
void addTrust(double);
void removeTrust(double);
};
The .cpp file
#include "function.h"
editPlayer::editPlayer(double trust) {}
// function implementation with argument - but argument is not used - change to void fun(double) -> fun(void) OR fun()
void editPlayer::addTrust(double trust) { trust +=5; }
void editPlayer::removeTrust(double trust) { trust -=5; }
I did an example with class declaration and member variables.
#include <iostream>
#include <string>
// this is a class declaration
class Player
{
protected: // protected member variables
double _trust;
public: // public interface
Player(double trust);
void addTrust(double);
void removeTrust(double);
double getTrust() const;
};
// Implementation of public interface
// notice _trust is the member defined in the class
Player::Player(double trust) : _trust(trust) {} // constructor
// example of default parameters (do note that only definition or declaration can have them)
// This means that calling the function without arguments will become 5
void Player::addTrust(double trust = 5) { _trust += trust; }
void Player::removeTrust(double trust = 5) { _trust -= trust; }
double Player::getTrust() const {return _trust; }
int main()
{
Player player(100); // this will invoke the constructor - and the player object will get initialised with the given state
std::cout << player.getTrust() << std::endl;
// variable to buffer input data into - assuming type int wrt. following if
int firstChoice;
//asks user choice
std::cin >> firstChoice;
if (firstChoice == 1)
{
player.addTrust(25);
player.addTrust();
}
std::cout << player.getTrust();
}
Happy coding !
so basically I was trying to save a class inside a .dat file but in my code but it says this error No matching member function for call to 'open' but I put fstream header. I don't know if I'm writing something wrong. I use Xcode 10.
class memberinformation
{
string name; //name
long int phonenumber; // phone number
int memberid; // member id
public :
memberinformation()
{ name="not assigned" ;
phonenumber=0;
memberid=0;
}
int option3();
int option2();
int option1();
int option4();
};
void wrt_file() //file function
{
memberinformation k;
fstream f;
f.open ("information.dat",ios::app,ios::binary) //this is where I get the error.
f.write((char*)&k,sizeof(k));
}
You are lucky to have been stopped by a simple error. #Alex44 has already shown how to get rid of the error:
f.open ("information.dat",ios::app|ios::binary); //this is where I get the error.
But the following line is even worse:
f.write((char*)&k,sizeof(k));
because the compiler will not show any error, while the content of the string will not be saved in the file. std::string is not trivially copiable and because of that, the memberinformation class is not either. So you should not try to write it to a file as raw bytes.
You should instead write a serialization function that writes to a binary stream (just a possible serialization way):
phonenumber as a long int (no problem there)
memberid as an int (no problem there)
name.size as a size_t
name.data as name.size bytes
The other two answers have answered:
Why its not compiling.
Why its a bad idea to write binary objects.
I would suggest that you serialize the object via the standard C++ technique of using the stream operators. This makes writting/reading the objects trivial and usually makes debugging problems easy.
Using the format suggested by #serge-ballesta in his post:
class memberinformation
{
string name; //name
long int phonenumber; // phone number
int memberid; // member id
public :
// OLD STUFF GOES HERE
void swap(memberinformation& other) noexcept
{
using std::swap;
swap(name, other.name);
swap(phonenumber, other.phonenumber);
swap(memberid, other.memberid);
}
friend std::ostream& operator<<(std::ostream& str, memberinformation const& data)
{
return str << data.phonenumber << " "
<< data.memberid << " "
<< data.name.size() << " "
<< data.name << " ";
}
friend std::istream& operator<<(std::istream& str, memberinformation& data)
{
memberinformation tmp;
std::size_t nameSize
if (str >> tmp.phonenumber >> tmp.memberid >> nameSize) {
// All sizes were read correctly.
tmp.name.resize(nameSize);
if (str.ignore(1).read(&tmp.name[0], nameSize)) {
// ignored the space and read the name correctly.
// So now we update the "data" object
tmp.swap(data);
}
}
return str;
}
};
Now in your code:
int main()
{
memberinformation object;
std::cout << object;
std::cin >> object;
std::ofstream file("Data.dat");
file << object;
}
You miss a semicolon and you need to "bitwise or" your flags:
void wrt_file() //file function
{
memberinformation k;
fstream f;
f.open ("information.dat",ios::app|ios::binary); //this is where I get the error.
...
}
The answers above address your initial problem. I'm going to talk about two more.
First, you probably should f.close() at the end of your method. It may be perfectly fine to let it drop out of scope and clean up from there, but I personally think that's ugly, and I wouldn't count on it.
Second, I wouldn't store the data in binary unless there's a really good reason to do it. It won't be portable. Serge above suggests a serialization method. I'd consider an alternate approach. I'd write to the file in a human readable form such as JSON. Yes, it's a little more work, but...
-If you change your class, your old files will still be readable
-They are portable across environments
-You can actually look at them and readily understand what they contain
So Serge's suggestions above aren't horrible, but I'd pick a more modern serialization / deserialization style.
Note that your f.write won't work because your object contains other objects, you don't know how they work under the hood. That string, for instance, almost certainly can't be dumped the way you're trying to do it. Plus you aren't only dumping your data.
Also, you should printf the sizeof(k). You might find it interesting information. Try to account for every byte. You could printf the sizeof(k.name) to help you work some of it out.
I'm almost positive the information doing so would surprise you, but I haven't actually done it myself, because I would never try to raw memory copy C++ objects, and that's in effect what you're trying to do.
I got stuck with creating a non-friend global function that has one parameter with pointer.
In simple words I need a function that get passesd object via pointer, and write out all its members.
So far I created a public declaration in MyClass
void WriteOutMyClass2 (MyClass *kp2);
And I created the function as well
void WriteOutMyClass2 (MyClass *kp2)
{
cout << "_a :" <<kp2._a <<endl;
}
but unfortunately I'm getting an error:
request for member ‘_a’ in ‘kp2’, which is of pointer type ‘MyClass*’ (maybe you meant to use ‘->’ ?)
I've pasted code at rexter.com, so you can look at that here.
http://rextester.com/URTI56137
And additionally I'm attaching the whole code here.
class MyClass
{
private:
int _a;
int* c;
int size;
static int counter;
public:
friend void WriteOutMyClass1 (MyClass &kp1);
void WriteOutMyClass2 (MyClass *kp2);
MyClass() //default constructor
{
_a=0;
size = 10;
c = new int [size];
for(int i = 0; i<size; i++)
{
c[i] = 1;
}
counter++;
}
};
//Initialize friend fucntion
void WriteOutMyClass1 (MyClass &kp1)
{
cout << "_a :" <<kp1._a <<endl;
cout << "size :" <<kp1.size<<endl;
cout << "counter :" <<kp1.counter<<endl;
for(int i = 0; i<kp1.size; i++)
{
cout << "c[" << i << "] = " << kp1.c[i] << endl;
}
}
//Initialize non-friend global fucntion.
void WriteOutMyClass2 (MyClass *kp2)
{
cout << "_a :" <<kp2._a <<endl; // here I'm getting error.
}
int main()
{
}
edit:
What excatly I'm trying to do is, get access to private members of MyClass from non-firend function declared outside MyClass.
Function shouldn't be static, and access to private members is needed via getter or not. I'm not aware of c++ possibilties.
I appreciate any help!
ps: the "->" isn't enough, because the "_a" field is private.
How would it looks with a getter?
edit2:
I unduerstand that some rules were broken but this code is an exercise I got from an university. It's specially done to show some approch.
Unfortunatelly variable names are as they are, of course I could rename them but I forgot.
The diagnostic is quite clear and even gives a suggestion.
You need
cout << "_a :" <<kp2->_a <<endl;
// ^^
with a -> not a . in the body of WriteOutMyClass2
BTW, you might add assert(kp2 != nullptr); before that. If kp2 happens to be null or invalid, you have undefined behavior (and probably a segmentation fault) and that is scary.
You could declare your WriteOutMyClass2 as a static function (I'm not sure you want that, your intentions are unclear).
BTW, don't be afraid of friend functions, even if having too much of them is bad smell. You might want to (and in your case, you probably should) define many getters and setters.
I recommend spending several days reading more about C++ (at least C++11) since it is a very difficult programming language. So read a good C++ programming book and look into some C++ reference site.
Don't forget to enable all warnings and debug information, so compile on the command line with g++ -Wall -Wextra -g if using GCC. Learn how to use the debugger (e.g. gdb).
Be aware of the (empirical) rule of five (which your code breaks, and that is a mistake). Prefer standard containers and smart pointers. Perhaps you might remove size and declare std::vector<int> _c; instead of having c (and size) as private members.
Later on, consider defining your own operator << for output of your types.
Study for inspiration the source code of several free software projects (e.g. on github) coded in C++.
What exactly I'm trying to do is, get access to private members of MyClass
Wrong approach. You should define getter functions, and they generally are public: (even if some of them could be private: or protected:).
the "->" isn't enough, because the "_a" field is private. How would it looks with a getter?
Your current code is in very bad shape. But you might add a getter member function:
// inside class MyClass
public:
int getA(void) const {return _a;};
and then use kp2->getA() instead of kp2->_a
BTW, you should consider more readable names (probably longer ones) for your public interface. If your member field _a is meant to be some price, its getter function should better be named getPrice (or perhaps just Price) than getA ...
It is important to keep your code readable (even to yourself, in a few months). Code is more often read than written (or compiled). Developer's time costs much more than computer time.
I'm currently trying to create a basic quiz game in C++.
The following code throws an error when I try to run it, it works if I don't use answer("answer") in the main class and instead substitute it with the actual code.
I wanted to "nest" (I don't know the technical term) some of the code so that I did not have to keep writing it out every time, as you can see i was hoping to write any question followed by answer("answer").
#include "stdafx.h"
#include <iostream>
#include <string>
using namespace std;
int main()
{
cout << "QUIZ C++ EDITION!\n";
cout << "Question 1:\n";
cout << "What is the colour you get when you mix red and yellow?\n\n";
question("Orange");
system("PAUSE");
}
void question(string answer) {
string input;
getline(cin, input);
if (input == answer) {
cout << "\nCorrectimundo!\n";
}
else
{
cout << "\nWrongimundo.\n";
}
return;
}
I have a feeling it's a case of wrong syntax but the IDE is not showing me where the error is unfortunately, it only happens when I run the program.
It looks like you are trying to make a function. Can I help?
– Clippy (1997-2007 RIP)
Two ways to do this. One is to forward declare question ahead of its first use.
void question(string answer);
int main()
{
...
question("Orange")
...
}
void question(string answer)
{ ... }
A forward declaration is a promise to the compiler that question will be fully defined somewhere else, maybe later in this file, maybe in another file, maybe in a library. But it must be defined somewhere or the program will compile, but it will not link.
And the other is to fully define question ahead of it's first use.
void question(string answer)
{ ... }
int main()
{
...
question("Orange")
...
}
I prefer the second approach because there is no possibility of falling into a trap like this:
void question(int answer);
int main()
{
...
question(42)
...
}
void question(string answer)
{ ... }
and getting a linker error from changing the forward declaration of question and forgetting to change the definition.
You need to provide a declaration of the function question before you can use it in main. Add
void question(string answer);
before the definition of main.
In C++ you must declare a function before you can use it (note, definition is also a declaration), but there is no mention of function question before line
question("Orange");
when it is actually trying to get called. Add a declaration:
void question(string answer);
int main()
{
// the rest of code ...
You forgot to declare your function , you can either declare it before main or just write the whole function before main.
You need to add before your main:
void question(string value);
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.