Initializing constant character pointer of a class - c++

I am trying to create a Person class in which I have decided to keep the name and gender constant. Here is the class definition:
class Person
{
const char *name;
int age;
const char *gen;
protected:
Person(const char *, const int ,const char *); // I want to use this class as a Base class
public:
~Person();
}
Now my problem is how to initialize the constant data members. I know that I have to use initialization lists for this task but even then how do I allocate memory for the char pointers with new? Also I cannot initialize these pointers in the constructor body. Please help me find a solution.

You can use the initializer list as following, you don't need to allocate the char array in this construction. I have simplified the class, as your question is about the const char*.
#include <iostream>
#include <string>
class Person
{
public:
Person(const char* name, const std::string better_name) :
name(name), better_name(better_name) {}
void print_name()
{
std::cout << name << " and " << better_name << std::endl;
}
private:
const char* name;
const std::string better_name;
};
int main()
{
Person person("Billy", "Better Billy");
person.print_name();
return 0;
}

Related

C2039 - FUNCTION Is not a member of CLASS

I'm experimenting a little bit with templated classes and I have found this error:
Error C2039 'getName': is not a member of 'Person<T>
This is my class structure:
struct professor
{
static const char name[];
static const age = 50;
};
struct student
{
static const char name[];
static const age = 21;
};
const char professor::name[] = "Jules";
const char student::name[] = "Michael";
// Please make the Person template class here.
template <class T>
class Person
{
public:
Person();
char[] getName();
private:
T & m_Person;
};
template<class T>
Person<T>::Person()
{
m_Person= T;
}
template<class T>
char* Person<T>::getName()
{
return m_Person.name;
}
Do you know what is failing?
In fact I don't know if the class definition etc are correct because I'm quite new with the templated classes so If you see any other error It would be great If you warn me.
THank you, I hope you can help me.
Fix compilation errors from first to last. char[] is not a valid return type, the function definition for getName() fails to compile that's why you get the error.
You are also missing the type specifier for the age member variables as C++ does not support default int.
Your code is a little confusing, I think you want something like this:
#include <string>
#include <iostream>
struct professor
{
std::string name;
int age;
};
struct student
{
std::string name;
int age;
};
template <class T>
class Person
{
public:
Person(const T& person) : m_Person(person) {}
std::string getName()
{
return m_Person.name;
}
private:
T m_Person;
};
int main() {
student s{"Michael", 21};
Person<student> p(s);
std::cout << p.getName();
return 0;
}
If you want to use a class with only static members as a template parameter, you don't need to store an instance:
#include <iostream>
struct S {
static const int x = 42;
};
template <typename T>
struct A {
int getValue() {
return T::x;
}
};
int main() {
A<S> a;
std::cout << a.getValue();
return 0;
}

Utilizing constructor, destructor, and printing off objects - c++

Read the comments too.
Basically, I am trying to figure out object constructors, destructor, and classes. I created a class with a few public member variables, and a few private member variables. At this point I am only utilizing the public members within my code.
My question is, to put it quite simply, how do I utilize the constructor, destructor, and print off the objects info to the console.
Thanks.
#include <iostream>
// Class -> NPC
// Contains generic stats for an NPC in a game
class NPC
{
public:
char name;
int age;
char favoriteItem;
private:
char quest;
char nemesis;
int karma;
}
// Object Constructor
NPC::NPC (char newName, int newAge, char newFavoriteItem)
{
name = newName;
age = newAge;
favoriteItem = newFavoriteItem;
}
// Object Deconstructor
NPC::~NPC()
{
// Do nothing
}
// Here I would like to create a new NPC, bob, with a name of "Bob", age of 28, and his favorite items being a Sword
// Next, I attempt to use this information as output.
int main()
{
NPC bob("Bob",28, "Sword");
std::cout << bob << std::endl;
}
Fixed the char (only one character) to std::string. I added initialization list and std::ostream &operator << operator.
http://en.cppreference.com/w/cpp/language/default_constructor
#include <iostream>
#include <memory>
#include <string.h>
class NPC
{
public:
std::string name;
int age;
std::string favoriteItem;
NPC(std::string const& name, int age, std::string favoriteItem)
: name(name), age(age), favoriteItem(favoriteItem)
{};
private:
char quest;
char nemesis;
int karma;
};
std::ostream &operator << (std::ostream &os, NPC const& npc)
{
os << npc.name << " " << npc.age << " " << npc.favoriteItem << "\n";
return os;
};
int main()
{
NPC npc("Bob", 28, "Sword");
std::cout << npc;
return 0;
}

how to copy part of char buffer to std::string?

I try to store instances of class Person in std::list Users. Before putting each instance to Users I want to copy first 10 bytes from buf to std::string Name. How can I do that?
class Person {
public:
Person(){ std::cout << "Constructing Person " << std::endl;}
private:
std::string Name;
};
int main() {
unsigned char buf[1024];
std::list<Person> Users;
Person ps;
Users.push_back(ps);
return 0;
}
You'll need to change your constructor for doing this:
class Person {
public:
Person(const char* buf_, size_type size_)
: name(buf_,size_) {
std::cout << "Constructing Person " << std::endl;
}
// ....
};
and in main() write
Person ps(buf,10);
You could provide an appropriate constructor for Person.
Person(std::string Name) : Name(std::move(Name)) {}
Definition of a Person would be
Person ps(std::string(buf, 10));
Or write directly:
Users.emplace_back( std::string(buf, 10) );

vector of char (*)[] casts

I'm working with some legacy code and I need a StoreStrings class storing
some strings and able to return a MyString*.
I've tried with this:
typedef char MyString[64];
class StoreStrings{
public:
void store(MyString *aStr)
{
theVec.push_back(aStr);
}
const MyString* get(){return theVec.begin();}
private:
std::vector<MyString> theVec;
};
But I'm disappointed since it doesn't compile with this syntax.
StoreStrings myStore;
myStore.store("Hello");//cannot convert parameter 1 from 'char [6]' to 'char (*)[64]'
I've to instantiate one MyString before.
MyString myStr = "Hello";
myStore.store(&myStr);
How can I rewrite the StoreStrings class so to have myStore.store("Hello"); compiling?
Arrays cannot be used in STL containers as it requires the type to be copy constructible and assignable
You may try following, however std::string approach is best.
typedef char MyString[64];
struct X{
MyString s;
};
class StoreStrings{
public:
void store(MyString aStr)
{
X temp ;
for(int i=0;aStr[i];++i)
temp.s[i] =*(aStr+i);
theVec.push_back(temp);
}
// Here iterator is returned.
const std::vector<X>::iterator get(){return theVec.begin();}
private:
std::vector<X> theVec;
};
int main(){
StoreStrings myStore;
MyString m ="Hello";
myStore.store(m);
}
I would suggest something like that
Storestring.h
#pragma once
#include <vector>
class StoreStrings
{
public:
void store(const char* aStr)
{
pszStr = new char[64];
strcpy_s(pszStr,64,aStr);
theVec.push_back(pszStr);
};
~StoreStrings(void){
for(std::vector<char*>::iterator it = theVec.begin();it!=theVec.end();++it){
delete *it;
}
};
std::vector<char*>::iterator getBegin(){return theVec.begin();};
std::vector<char*>::iterator getEnd(){return theVec.end();};
private:
char* pszStr;
std::vector<char*> theVec;
};
main.cpp
#include "StoreStrings.h"
#include <iostream>
int main(void){
StoreStrings s;
s.store("a");
s.store("b");
s.store("c");
for(std::vector<char*>::iterator it = s.getBegin();it!=s.getEnd();++it){
std::cout << *it<<std::endl;
}
return 0;
};

Crash on accessing reference to string

This code crashes at the cout line. Can anyone explain why this doesn't work?
#include <iostream>
#include <string>
using namespace std;
class myclass {
const string& m_str;
public:
myclass(string s) : m_str(s) {}
const string& getString() const { return m_str; }
};
int main () {
const string str("honey");
myclass mc(str);
cout << mc.getString() << "\n";
return 0;
}
the myclass constructor is taking a string by value which makes it a temporary. You're then binding this temporary to the m_str member. As soo as the constructor exits your member reference becomes invalid. Instead: myclass(const string& s) : m_str(s) {}
Even so that may not be a good idea. Generally speaking using references as members can be dangerous because you have to be very clear about lifetime semantics. You should consider just storing the string by value in your class unless you have a specific reason not to do so.