Related
An error pops up saying the class type does not provide a subscript operator.
I'm new to c++ and can't seem to figure this one out. Would be really thankful if you provided me some tips and where I'm going wrong in my code outside of the problem.
class Transaction {
protected:
char * ime;
char smetka[16];
float iznos;
Date d;
public:
Transaction() {}
Transaction( char * ime , char * smetka ,float iznos ,Date d ) {
this->ime = new char[strlen(ime)+1];
strcpy(this->ime,ime);
strcpy(this->smetka,smetka);
this->iznos=iznos;
this->d=d;
}
Transaction(const Transaction & c) {
ime = new char[strlen(ime)+1];
strcpy(this->ime,c.ime);
strcpy(this->smetka,c.smetka);
this->iznos=c.iznos;
this->d=c.d;
}
friend ostream & operator<<(ostream & out, const Transaction & c) {
if(c.iznos>0) {
return out << "Inflow " << c.iznos << " " << c.ime << "(" << c.smetka << ")-" << c.d.getDay() << "." << c.d.getMonth() << "." << c.d.getYear() << endl;
} else {
return out << "Outflow " << c.iznos << " " << c.ime << "(" << c.smetka << ")-" << c.d.getDay() << "." << c.d.getMonth() << "." << c.d.getYear() << endl;
}
}
Transaction(char * ime, char * smetka) {
this->ime = new char[strlen(ime)+1];
strcpy(this->ime,ime);
strcpy(this->smetka,smetka);
}
};
class TransactionAccount {
private:
char * ime;
char smetka[16];
Transaction * t;
int n;
int kapacitet;
public:
TransactionAccount() {
this->t = new Transaction[3];
this->kapacitet=3;
}
TransactionAccount(char * ime,char * smetka) {
this->ime = new char[strlen(ime)+1];
strcpy(this->ime,ime);
strcpy(this->smetka,smetka);
}
void addTransaction(Transaction & a) {
if(n<kapacitet) {
this->t = &a;
} else {
kapacitet*=2;
this->t = &a;
}
}
Transaction getTransList() {
return *t;
}
int getTransCapacity() {
return this->kapacitet;
}
int getTransNumber() {
return this->n;
}
virtual ~TransactionAccount() {}
};
int main() {
char name[50],number[16];
float amount;
int d,m,y;
int n;
bool isInflow;
TransactionAccount ta;
int testcase;
cin>>testcase;
switch (testcase) {
case 1: {
cout<<"------Transaction test------"<<endl;
cin>>name;
cin>>number;
cin>>amount;
cin>>d>>m>>y;
Transaction t(name,number,amount,Date(d,m,y));
cout<<t;
}
break;
case 2: {
cout<<"------TransactionAccount test:constructor, desctuctor & get-
functions------"<<endl;
cin>>name;
cin>>number;
TransactionAccount ta(name,number);
cin>>n;
for (int j=0; j<n; j++) {
cin>>name>>number>>amount>>d>>m>>y;
Transaction t(name,number,amount,Date(d,m,y));
ta.addTransaction(t);
}
cout<<"Capacity: "<<ta.getTransCapacity()<<endl;
cout<<"Number of elements: "<<ta.getTransNumber()<<endl;
cout<<(ta.getTransList())[n]; // -- here is the
problem
cin>>n;
cout<<"The element on position "<<n<<" is "<<endl;
}
return 0;
}
My desired result is that it calls the previous object(of the class) and prints it.
The answer to this specific question is that getTransList returns a single Transaction (rather than, as the name would suggest, the 'list'). The error then happens because Transaction does not have an overloaded subscript operator (which is fine; it probably shouldn't).
Transaction getTransList() {
return *t;
}
should be replaced with
Transaction* getTransList() {
return t;
}
which properly returns the array.
However, there are many other problems with the code provided. Some will become apparent when you try to run/debug the code; for the rest, while you can of course ask (new) questions about specific problems on this site, you might be better served consulting your teacher.
I am relatively new to classes and was introduced to copy constructors and overloading last week. I am supposed to overload the = operator and use it to assign multiple variables using the class name.
For some reason, running the program causes a popup saying
program.cpp has stopped responding.
I am positive there are minor/major things that I am missing due to me being a rookie with objects in C++.
Any advice is very much appreciated!
#include<iostream>
#include<string>
using namespace std;
class Employee
{
private:
char *name;
string ID;
double salary;
public:
Employee() {}
Employee(char *name, string eid, double salary) {}
Employee(const Employee &obj)
{
name = new char;
ID = obj.ID;
salary = obj.salary;
}
~Employee() {}
void setName(char *n)
{
name = n;
}
void setID(string i)
{
ID = i;
}
void setSalary(double s)
{
salary = s;
}
char getName()
{
return *name;
}
string getID()
{
return ID;
}
double getSalary()
{
return salary;
}
Employee operator = (Employee &right)
{
delete[] name;
ID = right.ID;
salary = right.salary;
return *this;
}
};
int main()
{
Employee e1("John", "e222", 60000), e2(e1), e3, e4;
e3 = e4 = e2;
e2.setName("Michael");
e2.setSalary(75000);
e3.setName("Aaron");
e3.setSalary(63000);
e4.setName("Peter");
cout << "\nName: " << e1.getName() << "\nID: " << e1.getID() << "\nSalary: " << e1.getSalary() << endl;
cout << "\nName: " << e2.getName() << "\nID: " << e2.getID() << "\nSalary: " << e2.getSalary() << endl;
cout << "\nName: " << e3.getName() << "\nID: " << e3.getID() << "\nSalary: " << e3.getSalary() << endl;
cout << "\nName: " << e4.getName() << "\nID: " << e4.getID() << "\nSalary: " << e4.getSalary() << endl;
return 0;
}
There are several issues with this code.
The first issue is in the constructor Employee(char *name, string eid, double salary) {} which is just doing nothing and ignoring the passed data whereas it should be using it to initialize the fields (class member data).
Employee(char *name, string eid, double salary)
{
const size_t bufferSize = strlen(name) + 1;
this->name = new char[bufferSize];
memcpy(this->name, name, bufferSize);
this->ID = eid;
this->salary = salary;
}
The second issue is in the copy constructor Employee(const Employee &obj) , where you are just initializing the name (with single byte of char) and that's it. What the copy constructor suppose to do is initialize the fields (class members) of the class with the fields of the class object being passed to it.
Employee(const Employee &obj)
{
const size_t bufferSize = strlen(name) + 1;
this->name = new char[bufferSize];
memcpy(this->name, name, bufferSize);
ID = obj.ID;
salary = obj.salary;
}
the third issue is with the default constructor which is suppose to initialize the name pointer with the NULL so that the destructor could clean it up nicely:
Employee() : name(NULL) {}
~Employee()
{
if (NULL != name)
delete[] name;
}
the fourth and last problem is with the assignment operator that's suppose to properly initialize the name member data instead of deleting it (which doesn't make sense)
Employee operator = (Employee &right)
{
if (NULL != this->name)
delete[] this->name;
const size_t bufferSize = strlen(right.name) + 1;
this->name = new char[bufferSize];
memcpy(this->name, right.name, bufferSize);
ID = right.ID;
salary = right.salary;
return *this;
}
The problem is this line:
delete[] name;
You shouldn't delete anything you haven't allocated with new first. If you delete the above line, your program kind of works. :)
Here's a slightly revised version of your program that works:
#include<iostream>
#include<string>
using namespace std;
class Employee
{
private:
char *name;
string ID;
double salary;
public:
Employee() {}
Employee(char *name, string eid, double salary)
: name (name) // ADDED THESE
, ID(eid)
, salary(salary)
{
}
Employee(const Employee &obj)
{
name = obj.name; // WAS: new char;
ID = obj.ID;
salary = obj.salary;
}
~Employee() {}
void setName(char *n)
{
name = n;
}
void setID(string i)
{
ID = i;
}
void setSalary(double s)
{
salary = s;
}
char * getName()
{
return name;
}
string getID()
{
return ID;
}
double getSalary()
{
return salary;
}
Employee operator = (const Employee &right)
{
name = right.name; // WAS: delete[] name;
ID = right.ID;
salary = right.salary;
return *this;
}
};
int main()
{
Employee e1("John", "e222", 60000), e2(e1), e3, e4;
e3 = e4 = e2;
e2.setName("Michael");
e2.setSalary(75000);
e3.setName("Aaron");
e3.setSalary(63000);
e4.setName("Peter");
cout << "\nName: " << e1.getName() << "\nID: " << e1.getID() << "\nSalary: " << e1.getSalary() << endl;
cout << "\nName: " << e2.getName() << "\nID: " << e2.getID() << "\nSalary: " << e2.getSalary() << endl;
cout << "\nName: " << e3.getName() << "\nID: " << e3.getID() << "\nSalary: " << e3.getSalary() << endl;
cout << "\nName: " << e4.getName() << "\nID: " << e4.getID() << "\nSalary: " << e4.getSalary() << endl;
return 0;
}
This is the photo of the model I have to resolve:
I have this class:
#include<iostream>
#include<fstream>
using namespace std;
class Word
{
protected:
char *value;
char type[20];
int noChars;
static int noWords;
public:
Word(char *value, char *type)
{
this->noChars = 0;
this->value = new char[strlen(value) + 1];
strcpy(this->value, value);
strcpy(this->type, type);
Word::noWords++;
}
Word()
{
this->noChars = NULL;
this->value = NULL;
strcpy(this->type,"Nedeterminat");
}
void operator=(Word &x)
{
this->noChars = x.noChars;
strcpy(this->type, x.type);
this->value = new char[strlen(x.value) + 1];
strcpy(this->value, x.value);
}
Word(const Word& x){
this->noChars = x.noChars;
strcpy(this->type, x.type);
this->value = new char[strlen(x.value) + 1];
strcpy(this->value, x.value);
}
char* getValue()
{
return this->value;
}
void setType(char* x)
{
if (x == NULL)
{
throw new exception("Tip gresit!");
}
else
{
strcpy(this->type, x);
}
}
char &operator[](int i)
{
if (i >= 0 && i <= (strlen(this->value) - 1))
{
return this->value[i];
}
else
cout << endl << "Eroare indice: " << i;
}
static int getNoWords()
{
return Word::noWords;
}
operator int()
{
return this->noChars;
}
friend ostream& operator<<(ostream&, Word&);
friend istream& operator>>(istream&, Word&);
};
ostream& operator<<(ostream& consola, Word& x)
{
consola << "Value: " << x.getValue() << endl;
consola << "Type: " << x.type << endl;
consola << "NoChars: " << x.noChars << endl;
return consola;
}
istream& operator>>(istream& consola, Word& x){
cout << "Value: "; consola >> x.value;
cout << "Type: "; consola >> x.type;
cout << "NoChars: "; consola >> x.noChars;
return consola;
}
int Word::noWords = 0;
class Dictionary{
private:
char *language;
int noWords;
bool isOnline;
Word v[100];
public:
Dictionary(char *language, Word w, int noWords, bool isOnline)
{
this->language = new char[strlen(language) + 1];
strcpy(this->language, language);
for (int i = 0; i < 100; i++)
{
this->v[i] = w;
}
this->noWords = noWords;
this->isOnline = isOnline;
}
};
int main()
{
//1
Word w1("exam", "noun");
/*Word w2;*/
Word w3 = w1;
cout << w3;
//2
cout << endl << "Word value: " << w3.getValue();
Word w2("to take", "noun");
w2.setType("verb");
//3
w3 = w2;
cout << endl << w3;
Word *pw = new Word("pointer", "noun");
delete pw;
//4
cin >> w3; cout << w3;
char character = w3[2];
cout << endl << character;
//5
double noChars = (int)w1;
cout << endl << noChars;
cout << endl << Word::getNoWords() << endl;
//6
Dictionary dictionary1("English", NULL, 0, false);
}
I have this main:
Dictionary dictionary1("English", NULL, 0, false);
How should I change the constructor to work? I receive a error :
Arrgument types are:(const char[8],int,int,bool);
And how should I write the default constructor?
NULL cannot be assigned to Word. Try Word() instead which will call the default constructor to Word. Consider changing that function parameter to const Word& - anonymous temporaries are allowed to bind to const references.
I'd prefer to see a std::string as the type for the member variable language; using a const std::string& as the function parameter. Then you will not have to worry about a subsequent delete call, and defining your own assignment operators and copy constructors. Currently, your class leaks memory.
You can not Assign null to the type Word. If you want to default it you should pass something like word()
Dictionary dictionary1("English", word(), 0, false);
EDIT:
The better approach,IMO, that will work for the same main() you have is like this:
class Dictionary{
private:
std::string language;
int noWords;
bool isOnline;
std::array<Word,100> v;
public:
Dictionary(std::string const& language, Word* w, int noWords, bool isOnline): language (language),isOnline(isOnline ),noWords(noWords)
{
for (int i = 0; i < 100; i++){
this->v[i] = (w==NULL)?word():*w;
}
}
};
So, I have a class called "music" and when I try to compile the code, it gives me the following errors:
Error 13 error C2664: 'music::music(const music &)' : cannot convert
argument 2 from 'const char [5]' to 'char' c:\users\andrei
bordeianu\documents\visual studio
2013\projects\mediaplus\mediaplus\source.cpp 362 1 MediaPlus
14 IntelliSense: no instance of constructor "music::music" matches
the argument list
argument types are: (const char [5], const char [5], const char [4], const char [12], int, const char [8], const char [5],
int) c:\Users\Andrei Bordeianu\Documents\Visual Studio
2013\Projects\MediaPlus\MediaPlus\Source.cpp 361 11 MediaPlus
This is the class:
// Music class.
class music {
char* song;
properties musicProperties;
public:
music() {
cout << "Apel constructor default muzica." << endl;
this->song = NULL;
}
music(char* songName, char name, char type, char path, float size, char artist, char title, int year) {
cout << "Apel constructor cu parametri muzica." << endl;
if (songName) {
this->song = new char[strlen(songName) + 1];
strcpy(this->song, songName);
musicProperties.setDataMusic(name, type, path, size, artist, title, year);
} else {
songName = NULL;
}
}
music operator=(const music &songName) {
cout << "Supraincarcare operator = pentru muzica." << endl;
this->song = new char[strlen(songName.song) + 1];
strcpy(this->song, songName.song);
}
music(const music &songName) {
cout << "Apel constructor de copiere muzica." << endl;
if (songName.song) {
this->song = new char[strlen(songName.song) + 1];
strcpy(this->song, songName.song);
} else {
song = NULL;
}
}
~music() {
cout << "Apel destructor muzica." << endl;
if (this->song) {
cout << "Apel destructor pentru: " << this->song << endl;
delete[] song;
}
}
friend char* getMusic(const music& m);
friend ostream& operator<<(ostream& out, music& m);
friend istream& operator>>(istream& in, music& m);
};
and this is the main:
void main() {
music m1;
music m2("ceva", "ceva", "mp3", "c:\data\music", 38, "Rihanna", "Stay", 2013);
music m3 = m1;
}
Ok, tried your suggestions, and changed to string, and now my app looks like this:
#include <iostream>
#include <string>
using namespace std;
// Properties class.
class properties{
string name;
string type;
string path;
float size;
// For images.
int width;
int height;
// For music.
string artist;
string title;
int year;
public:
properties() {
cout << "Apel constructor default proprietati." << endl;
this->name = "";
this->type = "";
this->path = "";
this->size = 0;
this->width = 0;
this->height = 0;
this->artist = "";
this->title = "";
this->year = 0;
}
properties(string name, string type, string path, float size, int width, int height, string artist, string title, int year) {
cout << "Apel constructor cu parametrii proprietati." << endl;
this->name = name;
this->type = type;
this->path = path;
this->size = size;
this->width = width;
this->height = height;
this->artist = artist;
this->title = title;
this->year = year;
}
char getName() {
return this->name;
}
char getType() {
return this->type;
}
char getPath() {
return this->path;
}
float getSize() {
return this->size;
}
int getWidth() {
return this->width;
}
int getHeight() {
return this->height;
}
char getArtist() {
return this->artist;
}
char getTitle() {
return this->title;
}
int getYear() {
return this->year;
}
void setName(string name){
this->name = name;
}
void setPath(string path){
this->path = path;
}
void setType(string type){
this->type = type;
}
void setSize(float size){
this->size = size;
}
void setWidth(int width){
this->width = width;
}
void setHeight(int height){
this->height = height;
}
void setArtist(string artist){
this->artist = artist;
}
void setTitle(string title){
this->title = title;
}
void setYear(int year){
this->year = year;
}
void setDataGeneral(string name, string type, string path, float size){
cout << "Apel setter general properties." << endl;
setName(name);
setType(type);
setPath(path);
setSize(size);
}
void setDataMusic(string name, string type, string path, float size, string artist, string title, int year){
cout << "Apel setter music properties." << endl;
setName(name);
setType(type);
setPath(path);
setSize(size);
setArtist(artist);
setTitle(title);
setYear(year);
}
void setDataImages(string name, string type, string path, float size, int width, int height){
cout << "Apel setter image properties." << endl;
setName(name);
setType(type);
setPath(path);
setSize(size);
setWidth(width);
setHeight(height);
}
// Constructor de copiere.
properties(const properties& p){
cout << "Apel constructor copiere properties." << endl;
this->name = p.name;
this->type = p.type;
this->path = p.path;
this->size = p.size;
this->width = p.width;
this->height = p.height;
this->artist = p.artist;
this->title = p.title;
this->year = p.year;
}
~properties(){
cout << "Apel destructor properties." << endl;
};
};
// Music class.
class music {
char* song;
properties musicProperties;
public:
music() {
cout << "Apel constructor default muzica." << endl;
this->song = NULL;
}
music(char* songName, string name, string type, string path, float size, string artist, string title, int year) {
cout << "Apel constructor cu parametri muzica." << endl;
if (songName) {
this->song = new char[strlen(songName) + 1];
strcpy(this->song, songName);
musicProperties.setDataMusic(name, type, path, size, artist, title, year);
} else {
songName = NULL;
}
}
music operator=(const music &songName) {
cout << "Supraincarcare operator = pentru muzica." << endl;
this->song = new char[strlen(songName.song) + 1];
strcpy(this->song, songName.song);
}
music(const music &songName) {
cout << "Apel constructor de copiere muzica." << endl;
if (songName.song) {
this->song = new char[strlen(songName.song) + 1];
strcpy(this->song, songName.song);
} else {
song = NULL;
}
}
~music() {
cout << "Apel destructor muzica." << endl;
if (this->song) {
cout << "Apel destructor pentru: " << this->song << endl;
delete[] song;
}
}
friend char* getMusic( music& m); //const
friend ostream& operator<<(ostream& out, music& m);
friend istream& operator>>(istream& in, music& m);
};
// Movies class.
class movies {
char* movie;
properties moviesProperties;
public:
movies() {
cout << "Apel constructor default filme." << endl;
movie = NULL;
}
movies(char* movieTitle, string name, string type, string path, float size) {
cout << "Apel constructor cu parametri filme." << endl;
if (movieTitle) {
this->movie = new char[strlen(movieTitle) + 1];
strcpy(this->movie, movieTitle);
moviesProperties.setDataGeneral(name, type, path, size);
} else {
movie = NULL;
}
}
movies operator=(const movies &movieTitle) {
cout << "Supraincarcare operator = pentru filme." << endl;
this->movie = new char[strlen(movieTitle.movie) + 1];
strcpy(this->movie, movieTitle.movie);
}
movies(const movies &movieTitle) {
cout << "Apel constructor de copiere filme." << endl;
if (movieTitle.movie) {
this->movie = new char[strlen(movieTitle.movie) + 1];
strcpy(this->movie, movieTitle.movie);
} else {
movie = NULL;
}
}
~movies() {
cout << "Apel destructor filme." << endl;
if (this->movie) {
cout << "Apel destructor pentru: " << this->movie << endl;
delete[] movie;
}
}
friend char* getMovies(const movies& m);
friend ostream& operator<<(ostream& out, movies& m);
friend istream& operator>>(istream& in, movies& m);
};
// Images class.
class images {
char* image;
properties imagesProperties;
public:
images() {
cout << "Apel constructor default imagini." << endl;
image = NULL;
}
images(char* imageName, string name, string type, string path, float size, int width, int height) {
cout << "Apel constructor cu parametri imagini." << endl;
if (imageName) {
this->image = new char[strlen(imageName) + 1];
strcpy(this->image, imageName);
imagesProperties.setDataImages(name, type, path, size, width, height);
} else {
image = NULL;
}
}
images operator=(const images &imageName) {
cout << "Supraincarcare operator = pentru imagini." << endl;
this->image = new char[strlen(imageName.image) + 1];
strcpy(this->image, imageName.image);
}
images(const images &imageName) {
cout << "Apel constructor de copiere muzica." << endl;
if (imageName.image) {
this->image = new char[strlen(imageName.image) + 1];
strcpy(this->image, imageName.image);
}
else {
image = NULL;
}
}
~images() {
cout << "Apel destructor muzica." << endl;
if (this->image) {
cout << "Apel destructor pentru: " << this->image << endl;
delete[] image;
}
}
friend char* getImages(const images& i);
friend ostream& operator<<(ostream& out, images& i);
friend istream& operator>>(istream& in, images& i);
};
char* getMovies(const movies& m) {
if (m.movie)
return m.movie;
else
return NULL;
}
char* getImages(const images& i) {
if (i.image)
return i.image;
else
return NULL;
}
char* getMusic(music& songName) { //const
if (songName.song)
return songName.song;
else
return NULL;
}
ostream& operator<<(ostream& out, music& s) {
out << "Melodia este: " << s.song << endl;
return out;
}
istream& operator>>(istream& in, music& s) {
char buffer[20];
cout << "Melodia: ";
in >> buffer;
s.song = new char[strlen(buffer) + 1];
strcpy(s.song, buffer);
return in;
}
void main() {
music m1;
music m2("ceva", "ceva", "mp3", "c:\data\music", 38, "Rihanna", "Stay", 2013);
music m3 = m1;
//cout << getMusic(m2) << endl;
//cout << m2;
//cin >> m2;
//cout << m2;
}
and it gives me the following error(s):
Error 1 error C2440: 'return' : cannot convert from 'std::string' to
'char' c:\users\andrei bordeianu\documents\visual studio
2013\projects\mediaplus\mediaplus\source.cpp 50 1 MediaPlus
etc...
What can I to to resolve this issue ? Thanks!
You should try
music(char* songName, char* name, char* type, char* path, float size, char* artist, char* title, int year);
since char is a single character not pointer to a C string. Even better you should use a modern string class instead of old pointer stuff.
You're trying to pass string types ("ceva", "mp3", etc) into char parameters. To solve this, change your constructor parameters from char to string.
In the signature, the function accpects a char for name, but you send a char*.
music(char* songName, char name, char type, char path, float size, char artist, char title, int year)
I think it should be:
music(char* songName, char* name, char* type, char* path, float size, char* artist, char* title, int year)
You got your anwser, use string types or pointers.
As to why this is happening: You are passing characters as values, which mean they get their own new char array instance, this is clashing with the const instance of the argument. This is why the first argument (which was an explicit pointer) didn't cause an error.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question appears to be off-topic because it lacks sufficient information to diagnose the problem. Describe your problem in more detail or include a minimal example in the question itself.
Closed 8 years ago.
Improve this question
I'm trying to put together an assignment here and got stuck on one point. The question is to create Person class with Student derived class. Then overload both << and >> operators. In the end create checking program to create array of 20 Persons and keep loading either Person or Student. At any point we can print what we have by far - Person output is Name char*/Age int/Parents *char[2], Student output is Name char*/Age int/ID int.
My problem is with the array point - I can't figure out how to implement this and right now I'm stuck with:
Array of pointers to person
We choose if its person/student
istream to get the data
Here is main code part:
#include <iostream>
#include <conio.h>
#include "Header.h"
using namespace std;
int main()
{
char choice;
Person* Tablica[20];
Person* temp;
int i = 0;
while (1)
{
cout << "choices:" << endl;
cout << "(p)erson, (s)tudent, s(h)ow, (e)nd" << endl;
choice = _getch();
if (choice == 'h' || choice == 'H'){
for (int n = 0; n < i; n++){
cout << *Tablica[n] << endl;
}
}
if (choice == 'e' || choice == 'E'){ break; }
if (choice == 'p' || choice == 'P'){
temp = new Person;
cin >> *temp;
Tablica[i] = temp;
cout << *Tablica[i] << endl;
i++;
}
if (choice == 'S' || choice == 's'){
temp = new Student;
cin >> *temp;
Tablica[i] = temp;
cout << *Tablica[i] << endl;
i++;
}
}
system("PAUSE");
return 0;
}
I'm able to load first person/student and then code breaks without error.
So what I'm asking here is, could you look at the code and perhaps point me in the right direction?
Disclaimer: We have to use array, no vectors etc. Yes, conio.h is there as well and it has to stay... Obviously I'm beginner.
Person:
#include <iostream>
class Person
{
public:
Person();
Person(const Person&);
Person(char* n, int a, char* Parent1, char* Parent2);
char* getName();
int getAge();
char* getDad();
char* getMum();
virtual ~Person();
virtual Person operator=(const Person &);
virtual Person operator+(const Person &);
virtual Person operator+=(Person &);
virtual void write(std::ostream&);
virtual void read(std::istream&);
friend std::istream& operator>>(std::istream&, Person &);
friend std::ostream& operator<<(std::ostream&, Person &);
protected:
char* name;
int age;
char* ParentName[2];
};
class Student : public Person
{
public:
Student();
Student(const Student&);
Student(char* name, int age, int id);
virtual ~Student();
int ident();
Student operator=(const Student &);
Student operator+(const Student &);
Student operator+=(Student &);
virtual void write(std::ostream&);
virtual void read(std::istream&);
friend std::istream& operator>>(std::istream&, Student &);
friend std::ostream& operator<<(std::ostream&, Student &);
private:
int ID;
};
Class
#include "Header.h"
Person::Person(){
name = 0;
age = 0;
ParentName[0] = 0;
ParentName[1] = 0;
}
Person::Person(const Person & other)
{
name = other.name;
age = other.age;
ParentName[0] = other.ParentName[0];
ParentName[1] = other.ParentName[1];
}
Person::Person(char* n, int a, char* Parent1, char* Parent2){
name = n;
age = a;
ParentName[0] = Parent1;
ParentName[1] = Parent2;
}
Person::~Person(){}
char* Person::getName(){ return name; }
int Person::getAge(){ return age; }
char* Person::getDad(){ return ParentName[0]; }
char* Person::getMum(){ return ParentName[1]; }
Person Person::operator=(const Person & other){
name = other.name;
age = other.age;
ParentName[0] = other.ParentName[0];
ParentName[1] = other.ParentName[1];
return *this;
}
Person Person::operator+=(Person & other){
int i;
i = strlen(name) + strlen(other.name) + 4;
char * temp = new char[i];
strcpy_s(temp, i, name);
strcat_s(temp, i, " - ");
strcat_s(temp, i, other.name);
name = temp;
Person wynik(name, age, ParentName[0], ParentName[1]);
return wynik;
}
Person Person::operator+(const Person & other){
int i;
i = strlen(name) + strlen(other.name) + 4;
char * temp = new char[i];
strcpy_s(temp, i, name);
strcat_s(temp, i, " - ");
strcat_s(temp, i, other.name);
Person wynik(temp, age, ParentName[0], ParentName[1]);
return *this;
}
void Person::write(std::ostream& os)
{
os << "Osoba: name = " << this->getName() << ", wiek = " << this->getAge() << ", rodzice: " << this->getDad() << ", " << this->getMum();
}
std::ostream& operator<<(std::ostream& os, Person & other){
other.write(os);
return os;
}
void Person::read(std::istream& is)
{
char* name;
name = new char;
std::cout << "name: " << std::endl;
is >> name;
std::cout << "age: " << std::endl;
int age;
is >> age;
std::cout << "dad: " << std::endl;
char* dad;
dad = new char;
is >> dad;
std::cout << "mum: " << std::endl;
char* mum;
mum = new char;
is >> mum;
Person p(name, age, dad, mum);
*this = p;
}
std::istream & operator>>(std::istream & is, Person & os){
os.read(is);
return is;
}
Student::Student() : Person(){}
Student::Student(const Student& student) : Person(student){
ID = student.ID;
}
Student::Student(char* name, int age, int id) : Person(name, age, 0, 0){
ID = id;
}
Student::~Student(){}
Student Student::operator=(const Student & student){
Person::operator=(static_cast<Person const&>(student));
ID = student.ID;
return *this;
}
Student Student::operator+=(Student & student){
Student wynik(*this);
wynik.Person::operator=(wynik.Person::operator+=(student));
return wynik;
}
Student Student::operator+(const Student& student)
{
Person::operator+(static_cast<Person const&>(student));
return *this;
}
void Student::write(std::ostream& os)
{
os << "Student: name = " << this->getName() << ", age = " << this->getAge() << ", legitymacja: " << this->ident() << std::endl;
}
int Student::ident(){ return ID; }
std::ostream& operator<<(std::ostream& os, Student & other){
other.write(os);
return os;
}
void Student::read(std::istream& is)
{
char* name;
name = new char[20];
std::cout << "name: " << std::endl;
is >> name;
std::cout << "age: " << std::endl;
int age;
is >> age;
std::cout << "ID: " << std::endl;
int id;
is >> id;
Student s(name, age, id);
*this = s;
}
std::istream & operator>>(std::istream & is, Student & st){
st.read(is);
return is;
}
Does this compile?
Table[i] = *temp;
Table is an array of pointers to Person
temp is a pointer to Person
You are trying to put an object into an array that holds pointers. Dereferencing *temp gives you an object - you need a pointer to an object, so don't dereference it there. I would expect the compiler to complain about that... does it?
Also, check your second if statement - it says (choice == 'S' || choice == 'p'), which is probably not what you meant. Both if blocks will execute if choice == 'p'...
And in Person::read() you've only allocated a single character for name. That is likely to end badly...