I'm trying to initialize an instance of a class called "Winery" using an initialization list in the constructor for another class called "List." The problem is that when I hand the Winery constructor a winery to copy, it fails to copy the information.
This the header file for the Winery class:
class Winery
{
public:
Winery(const char * const name,
const char * const location,
const int acres,
const int rating);
virtual ~Winery(void);
const char * const getName() const { return name; }
const char * const getLocation() const { return location; }
const int getAcres() const { return acres; }
const int getRating() const { return rating; }
private:
char *name;
char *location;
int acres;
int rating;
};
Here is the relevant part of the header file for my List class:
struct Node
{
Node(const Winery& winery);
Winery item;
Node *nextByName;
Node *nextByRating;
};
Here is the constructor in my List class:
List::Node::Node(const Winery& winery) :
item(winery.getName(),
winery.getLocation(),
winery.getAcres(),
winery.getRating()),
nextByName(nullptr),
nextByRating(nullptr)
{
}
From what I see, it looks like I'm doing everything I need to be doing. The data members of the winery that I'm passing to the constructor are private, so I'm trying to get them via the functions that get information. They're in the proper order and everything.
The pointers work just fine after I initialize them, but the information isn't there, so I really don't know what to do here. If you're wondering, this is for an assignment and we have to use initialization lists (I've tried it without them and that doesn't work either so I really don't know what to do).
Here is my Winery constructor:
Winery::Winery(const char * const name,
const char * const location,
const int acres,
const int rating) :
acres(acres),
rating(rating)
{
char *newName = new char[sizeof(name) + 1];
char *newLocation = new char[sizeof(location) + 1];
}
From the looks of it, these lines:
char *newName = new char[sizeof(name) + 1];
char *newLocation = new char[sizeof(location) + 1];
do essentially nothing, as the location and name strings are not assigned or even written, which is probably the root of the problem. Your acres and rating should have been properly constructed, however.
Here is a working version I've created (also at Ideone):
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
class Winery
{
public:
Winery(const char * const name, const char * const location, const int acres, const int rating) :
name(strdup(name)),
location(strdup(location)),
acres(acres),
rating(rating)
{
}
virtual ~Winery(void)
{
free(name);
free(location);
}
const char * const getName() const { return name; }
const char * const getLocation() const { return location; }
const int getAcres() const { return acres; }
const int getRating() const { return rating; }
private:
char *name;
char *location;
int acres;
int rating;
};
struct Node
{
Node(const Winery& winery);
Winery item;
};
Node::Node(const Winery& winery) :
item(winery.getName(), winery.getLocation(), winery.getAcres(), winery.getRating())
{
}
int main()
{
Winery winery("Mission Hill Winery", "Kelowna, BC, Canada", 646, 4);
Node node(winery);
printf("%s\n", node.item.getName());
printf("%s\n", node.item.getLocation());
printf("%i\n", node.item.getAcres());
printf("%i\n", node.item.getRating());
}
Output:
Mission Hill Winery
Kelowna, BC, Canada
646
4
Related
I have a simple filesystem containing either a file or a directory. I have created an abstract class as a parent of both of these classes + two functions Size() and Change() as can be seen here:
class AbstractParent {
public:
explicit AbstractParent (const string & name = "", const unsigned int size = 0) : cString(name), cSize(size) {};
virtual ~AbstractParent() = default;
virtual unsigned int Size() const = 0;
unique_ptr<AbstractParent> Clone() const {
unique_ptr<AbstractParent> other(this->deepClone());
return other;
}
protected:
string cString;
unsigned int cSize;
//virtual copy constructor
virtual AbstractParent * deepClone() const = 0;
};
class CFile : public AbstractParent
{
public:
// constructor
explicit CFile (const string & hash, const unsigned int size) : AbstractParent(hash,size) {};
// Size
unsigned int Size() const override{
return cSize;
}
// Change
CFile & Change (const string & newHash, const unsigned int newSize) {
cString = newHash;
cSize = newSize;
return *this;
}
//virtual copy constructor
CFile * deepClone () const override{
return new CFile(*this);
}
};
class CDirectory : public AbstractParent
{
public:
// constructor
explicit CDirectory () {
systemMap = new map<string, unique_ptr<IFileSystem>>; //valgrind reports a leak here
};
// Size
unsigned int Size () const override {
return cSize;
}
// Change
CDirectory & Change (const string & FSName,const IFileSystem & file) {
systemMap->insert(make_pair(FSName, file.Clone()));
return *this;
}
//virtual copy
CDirectory * deepClone () const override {
return new CDirectory(*this);
}
private:
map<string, unique_ptr<IFileSystem>> * systemMap;
};
I have a problem with insering a directory into another directory. I would like to use a map for the directory, where the key is the name of the file/directory and its value is a pointer to the instance of it.
Here I have attempted to make it function with a virtual copy constructor and while it does compile, it does not work properly.
Valgrind is reporting lost memory where I allocate new map.
code in main to test out my implementation:
int main ()
{
CDirectory root;
stringstream sout;
root.Change("file.txt", CFile("jhwadkhawkdhajwdhawhdaw=", 1623))
.Change("folder", CDirectory()
.Change("fileA.txt", CFile("", 0).Change("skjdajdakljdljadkjwaljdlaw=", 1713))
.Change("fileB.txt", CFile("kadwjkwajdwhoiwhduqwdqwuhd=", 71313))
.Change("fileC.txt", CFile("aihdqhdqudqdiuwqhdquwdqhdi=", 8193))
);
return 0;
}
While debugging, everything gets inserted into the map of root as intended.
Only problem that remains is the memory of the map is lost.
Where should I free this memory, if it does not get freed implicitly?
How can I copy all the objects to another set of objects. I created a temporary object so I can add the current "robot" to the "robotSquad". I am trying to dynamically add it
I am new to the concept of operator overloading, I might have the wrong assumption on what I'm doing. Im using the += operator, making a temp if there is no space in "robotSquad" adding it to temp then copying it to the original robotSquad named r_robot.
I could possibly be doing all this wrong, need help Thanks!
RobotSquad& RobotSquad::operator+=(const Robot& p_robot) {
if (count <= sizeof(r_robots)) {
//how do i copy?
RobotSquad temp[count+1];
temp[count]=p_robot;
for(int i=0 ;i<=sizeof(r_robots);i++){
temp[i]=r_robots[i];
}
} else {
this ->r_robots[count]=p_robot;
}
count++;
return *this;
}
class RobotSquad {
char* name ;
Robot *r_robots;
int count;
public:
//constructor
RobotSquad();
RobotSquad(Robot* , int, char* p_name= "No name");
~RobotSquad();
//getters
char* getName();
Robot* getRoster();
int getCount();
//setters
char setName();
Robot setRobot();
int setCount();
//other
RobotSquad& operator+=(const Robot&);
private:
void setEmpty();
};
With std, it could be:
class RobotSquad {
std::vector<Robot> robots;
std::string name;
public:
//constructor
RobotSquad() = default;
explicit RobotSquad(const std::vector<Robot>& robots,
const std::string& name= "No name")
: robots{robots}, name{name}
{}
~RobotSquad() = default;
RobotSquad& operator+=(const Robot& robot)
{
robots.push_back(robot);
return *this;
}
// ...
};
I would like to convert this constructor's argument from const char* to std::string, but I don't know how to copy the new name to name properly.
Player::Player(const char* name) :
level(1),life(1),strength(1),place(0){
char* new_player_name = new char[strlen(name) + 1];
strcpy(new_player_name, name);
this->player_name = new_player_name;
}
Player::Player(string name) :
level(1),life(1),strength(1),place(0){
string new_player_name(' ',name.length() + 1); //#1
// I didn't know how to proceed
}
The classes data-members:
class Player {
char* player_name;
int level;
int life;
int strength;
int place;
};
Consider making player_name a std::string.
Then your constructor could start
Player::Player(const char* name) : player_name(name)
{
and you don't need to fiddle about with all those dynamically allocated char arrays.
You could change the type of name to a const std::string& too:
Player::Player(const std::string& name) : player_name(name)
{
i have a problem to delete an "Member" from a "Group" by index:
#include <vector>
#include <string>
using namespace std;
class Member
{
public:
explicit Member(const string &name, const unsigned long &key) : m_name(name), m_key(key) {}
const string &getName() const {return m_name;};
const unsigned long &getKey() const {return m_key;};
private:
string m_name;
unsigned long m_key;
};
//------------------------------------------------------------------------
class Group
{
public:
explicit Group(const string &name) : m_name(name) {}
const string &getName() const {return m_name;};
void addMember(const Member &member) {m_member.push_back(member);};
const vector<Member> &getMember() const {return m_member;};
private:
string m_name;
vector<Member> m_member;
};
void main() {
vector<Group> group;
group.push_back(Group("Membergroup 1"));
group[0].addMember(Member("Mark", 123456));
group[0].addMember(Member("John", 234567));
group[0].getMember().erase(group[0].getMember().begin() + 1); //to delete John
}
Error: : passing 'const std::vector' as 'this' argument discards qualifiers [-fpermissive] group[_group].getMember().erase(group[_group].getMember().begin() + 1);
Can someone help me please?
The problem is here:
const vector<Member> &getMember() const {return m_member;};
The function getMember() (which I suggest to call as getMembers()) returns a const reference to the vector.
Since constness, the compiler prevents modifications.
You can fix just refactoring in the following way:
class Group
{
public:
// ...
const vector<Member>& getMembers() const { return m_member; }
vector<Member>& getMembers() { return m_member; }
// ...
There are a lecture class and student class. We are trying to save student information on lecture class with arrays.
For example:
Student * studentList = new Student[numberOfStudent];
studentAdd("Mary");
studentDelete("Mary");
Problem:
User is not giving number of student and number of student is increasing when user add a new one with a one of lecture method. So I think that i need a list like structer to save them but it is forbidden for this work. Do you have any efficient ideas than my temporary solution?
My temporary solution:
Saving number of student and array size and when number of student is more than size copy array to a new one which is bigger than old one.
This question is related to my assigment which we are forcing to this by
*using dynamically allocated memory using pointers
*without using any static arrays with fixed sizes or other data structures such as
vector from the standard library
you could just use functions if you don't want to use objects. Note that I haven't compiled this code.
#include <iostream>
#include <sstream>
#include <string>
#include "Student.h"
void add(Student **list, Student *rhs);
void destroy(Student **list,int const &idx);
void destroy(Student **list,const char* student_name); //find the student name and delete
void resize(Student **list,int const &idx);
Student** begin(Student **list,); //get the first Student
Student** end(Student **list,); //the end of the array
void clear(Student **list,); //drop all Students
int main(int argc, char **argv)
{
if(argc < 2)
{
stc::cerr << "not enough parameters" << std::endl;
}
istringstream buffer(argv[1]);
int value;
buffer >> value;
Student ** studentList = new *Student[value];
int s
add(studentList, "Mary");
destroy(studentList, "Mary");
return(0);
}
void add(Student **list, Student *rhs) { /*definition*/ }
void destroy(Student **list, int const &idx) { /*definition*/ }
void destroy(Student **list, const char* student_name) { /*definition*/ }
void resize(Student **list, int const &idx) { /*definition*/ }
Student** begin(Student **list) { /*definition*/ }
Student** end(Student **list) { /*definition*/ }
void clear(Student **list) { /*definition*/ }
Now just define all that and you are all set
I do not recommend this approach
I would use objects... and taking into account what PaulMcKenzie said about capacity
class StudentList
{
private:
Student **list;
std::size_t size;
std::size_t capacity;
public:
StudentList(){}
~StudentList(){ this->clear(); }
inline void add(Student *rhs) { //definition }
inline void destroy(int const &idx) { //definition }
inline void destroy(const char* student_name) { //definition }
inline void resize(int const &idx) { //definition }
inline Student** begin() { //definition }
inline Student** end() { //definition }
inline void clear() { //definition }
};
And if possible
Iterators
Underneath vector you will find a similar implementation, it uses Iterators to encapsulate the Student**.