I have an object with a method that needs to mutate an outside instantiated object. I've been trying to reference the object in the parameter and that is clearly not working. This is what I have:
#include <iostream>
#include <cstdlib>
#include "Character.h"
using namespace std;
class TesterClass {
public:
void printStuff();
TesterClass(Character& userChar);
private:
Character& character;
};
TesterClass::TesterClass(Character& userChar)
{
character = userChar;
}
int main() {
Character userCharacter;
TesterClass tester(userCharacter);
return 0;
}
My question is how to can I use the instantiated tester class to edit the Character object via parameter passing. I'm very new at C++ and I've read every perceivable definition of reference and point passing, and it just doesn't seem to want to click.
Your constructor should be:
TesterClass::TesterClass(Character& userChar):character(userChar){}
Also see this question.
To address the comment, here's example code where the value is modified:
#include <iostream>
#include <cstdlib>
typedef char Character;
using namespace std;
class TesterClass {
public:
void printStuff();
TesterClass(Character& userChar);
private:
Character& character;
};
TesterClass::TesterClass(Character& userChar):character(userChar)
{
}
void TesterClass::printStuff() {
cout << character << endl;
cout << ++character << endl;
}
int main() {
Character userCharacter = 'a';
TesterClass tester(userCharacter);
tester.printStuff();
cout << userCharacter << endl;
++userCharacter;
cout << userCharacter << endl;
tester.printStuff();
return 0;
}
The output is
a
b
b
c
c
d
I agree with the previous answer/comments - You really should use an initialization list in your constructor. The thing is that your data-members are initialized through the initialization list (this happens BEFORE the body of the constructor is called). In your case, you have a Character& as a member. Since this is a reference, it HAS to be assigned something. I'm not sure which compiler you're using, but AFAIK that code shouldn't even compile.
What you're probably looking for is passing the reference in your main-method, like:
int main()
{
Character userCharacter;
// Notice the use of the &-operator
TesterClass tester(&userCharacter);
return 0;
}
At this point, you're no longer talking about a Character-instance, but of the memory address of the instance. So, since you're passing the mem-address, it's actually a pointer you need in your class, not a reference. (For instance, userCharacter.SomeMethod() is synonymous to (&userCharacter)->SomeMethod() where & references and -> dereferences).
Instead, you could write your TesterClass as:
class TesterClass
{
public:
void printStuff();
TesterClass(Character* userChar);
private:
Character* character;
};
TesterClass::TesterClass(Character* userChar)
: character(userChar) // <- Notice the init-list
{}
That way, in your TesterClass instance, you'll have a pointer that points to the same memory address where the userChar-instance resides.
As a sidenote: It can be good to notice though that userCharacter is a local variable, which means that it'll be destroyed when it runs out of scope. In this case it's not really a problem since tester is local as well. But if you're not used to working with pointers - Just a word of caution. Make sure you never pass the pointer (since you're storing the address in a class member) to a TesterClass-object that lives beyond the scope of the variable whose reference you're passing. That'll leave you with a dangling pointer.
I hope that helps you :)
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 !
I am new to C++ and get confused about what goes on under the hood when a class method returns a reference to a member variable that is raw data (rather than a pointer or a reference). Here's an example:
#include <iostream>
using namespace std;
struct Dog {
int age;
};
class Wrapper {
public:
Dog myDog;
Dog& operator*() { return myDog; }
Dog* operator->() { return &myDog; }
};
int main() {
auto w = Wrapper();
// Method 1
w.myDog.age = 1;
cout << w.myDog.age << "\n";
// Method 2
(*w).age = 2;
cout << w.myDog.age << "\n";
// Method 3
w->age = 3;
cout << w.myDog.age << "\n";
}
My question is: what happens at runtime when the code reads (*w) or w-> (as in the main function)? Does it compute the address of the myDog field every time it sees (*it) or it->? Is there overhead to either of these two access methods compared to accessing myDog_ directly?
Thanks!
Technically, what you are asking is entirely system/compiler-specific. As a practicable matter, a pointer and a reference are identical in implementation.
No rational compiler is going to treat
(*x).y
and
x->y
differently. Under the covers both usually appears in assembly language as something like
y(Rn)
Where Rn is a register holding the address of x and y is the offset of y into the structure.
The problem is that C++ is built upon C which in turn is the most f*&*) *p programming language ever devised. The reference construct is a work around to C's inept method of passing parameters.
I've searched endlessly on SE for a logical explanation for why this is happening. It is probably something very simple that I've overlooked, however I cannot spot it and would really appreciate some assistance with this.
Last week I implemented a class to read the output of a system call from a .ini file and then find and store the required information into custom objects that are then stored in a vector inside a Config class. It is a Singleton config class storing a unique_ptr for each instance of my custom class that is created.
The thing is, when I implemented this last week on my laptop, I had zero issues reading and writing to my member vector and was able to get it working exactly how I needed it. Since pulling to my desktop computer, this vector, and any STL container that I use as a member of my class, throws a segmentation fault when I try to do anything on it, even get it's size.
I've tried to shorten the code below to only include sections that actually use this vector. I have replaced my config with A, and custom class with T, and no matter where I try to use my member container, or any other test STL containers that I add to the class, I get a segfault.
For the record, I am using Qt with C++11.
Update: This example breaks on line 50 of c.cpp when debugging, and anywhere that tries to call the vector.
Debug points to this line in stl_vector.h
// [23.2.4.2] capacity
/** Returns the number of elements in the %vector. */
size_type
size() const _GLIBCXX_NOEXCEPT
/*-> this line */ { return size_type(this->_M_impl._M_finish - this->_M_impl._M_start); }
main.cpp
#include "c.h"
int main(int argc, char *argv[])
{
C *c = C::getInstance();
delete c;
return 0;
}
t.h - Class stores information from file
#include <string>
class T
{
public:
T();
bool Active();
std::string getA();
void setA(std::string);
private:
std::string a;
};
t.cpp
#include "t.h"
T::T()
{
}
bool T::Active()
{
if(a == "")
{
return false;
}
return true;
}
std::string T::getA()
{
return this->a;
}
void T::setA(std::string newa)
{
this->a = newa;
}
c.h - Class stores T objects and parses file for information
#include "t.h"
#include <QDebug>
#include <vector>
#include <algorithm>
#include <iostream>
#include <memory>
#include <sstream>
#include <fstream>
class C
{
public:
static C* getInstance();
private:
C();
static C* instance;
static bool init;
std::vector<std::unique_ptr<T>> t_list;
void readLines(const std::string&);
};
c.cpp
#include "c.h"
bool C::init = false;
C* C::instance = nullptr;
C::C()
{
system("echo this is a test command > a.ini");
instance->readLines("a.ini");
}
C* C::getInstance()
{
if(!init)
{
instance = new C;
init = true;
}
return instance;
}
void C::readLines(const std::string &path)
{
T* new_t;
std::ifstream file(path.c_str());
if(!file.is_open())
{
qDebug() << "Unable to open " << path.c_str();
}
std::ofstream o("test.txt");
std::string line;
while(std::getline(file, line))
{
// Split string before searching
std::stringstream ss(line);
std::string seg;
std::vector<std::string> split;
std::string left, right;
// Search patterns
size_t find_a = line.find("a");
size_t del = line.find(':');
if(find_a != std::string::npos)
{
o << "test_Size: " << t_list.size() << std::endl;
if(new_t->Active())
{
T* temp = new_t;
std::unique_ptr<T> move_t(temp);
t_list.push_back(std::move(move_t));
}
o << "test: " << t_list.size() << std::endl;
std::string n;
// Check if previous ahas any null elements
// Split string to find a
n = line.substr(line.find("a "));
n = n.substr(n.find(" ", +2));
new_t->setA(n);
}
else
{
continue;
}
}
// Add last a
T* t = new_t;
std::unique_ptr<T> move_t(t);
//t_list.push_back(std::move(move_t));
o << "a: " << t_list.back().get()->getA() << std::endl;
o << t_list.size() << std::endl;
o.close();
file.close();
}
UPDATE after code change:
I see two things now: One is that new_t in C::readlines is never initialized, so this could break when new_t->Active() is called a bit later in the function. However, I believe that the main problem you're running into is in C::C(), where it says
instance->readLines("a.ini");
At this point in the execution, C::instance is not yet initialized -- you're only just constructing the object that would later be assigned to it. Because of this, this in the readlines call is invalid, and any attempt to access object members will cause UB. This latter problem can be fixed by just calling
readLines("a.ini");
in which case the currently constructed object (that will later be instance) is used for this. I have no idea what you want to happen for the first, though, so all I can say is: If you want to have a vector<unique_ptr<T>>, you will have to create objects of type T with either new T() or (arguably preferrably) std::make_unique<T>() and put them in there.
I'll also say that this is a rather ugly way to implement a singleton in C++. I mean, singletons are never really pretty, but if you're going to do it in C++, the usual way is something like the accepted answer of C++ Singleton design pattern .
Old answer:
The problem (if it is the only one, which I cannot verify because you didn't provide an MCVE) is in the lines
T move_t = new_T;
std::unique_ptr<Adapter> ptr_t(&move_t); // <-- particularly this one
m_ts.push_back(std::move(ptr_t));
You're passing a pointer to a local object into a std::unique_ptr, but the whole purpose of std::unique_ptr is to handle objects allocated with new to avoid memory leaks. Not only will the pointer you pass into it be invalid once the scope surrounding this declaration is left, even if that weren't the case the unique_ptr would attempt to delete an object that's not on the heap at the end of its lifecycle. Both problems cause undefined behavior.
To me, it looks as though you really want to use a std::vector<T> instead of std::vector<std::unique_ptr<T>>, but that's a design issue you'll have to answer yourself.
Answering my own question here. I am trying to call a member variable from within the constructor of the object that holds it, so the vector I am trying to access is not yet instantiated and doesn't exist in memory. That is what causes the Segmentation fault to occur, I am trying to access memory that is not allocated yet, hence any call acting on any member of my C class was causing this issue.
I fixed this problem by adding a public function to the class that then calls the private readLines() function. I call that public function from the object that will take ownership of it, and since this occurs after it has been instantiated, the memory is accessible and the problem disappears.
in first, want to start to mention that it could be sorry for my bad english.
in C++, when we want to create a instance of certain type of class, we usually use "ClassType ObjectName;"
for example,
class Foo {};
Foo instance1;
but, i've met some codes make me embarassment a little. it following next.
class A {/*....bla bla*/};
class B {
public:
B(char*) {}
};
void main() {
A aaa;
B(aaa); // this makes a error.
}
by trial and error, i could know that "B(aaa);" is exactly same to "B aaa;".
But why? is this a kind of what depicted on standard documents? if so, please let me know where i can see.
Thanks in advance.
UPDATE:
Thank you for your all replies.
But i think that i've omitted some codes. Sorry.
#include <iostream>
using namespace std;
class A
{
};
class B
{
public:
B() { cout << "null\n"; }
B(char* str) {}
void print() {
cout << "print!\n";
}
};
void main()
{
A aaa;
//B(aaa); this line makes a error that says 'redefinition; different basic types'. VS2008
B(aa1);
aa1.print();
}
Output:
null
print!
as you can see, "B(aa1)" statement means not to pass aa1 to constructor as argument, but to create a instance aa1.
Until now, I've known "B(argument)" to "Pass argument to propel one of a overloaded construtor, and create a nameless temporary instance".
but value "aa1" looks lke neither a defined value nor a temporary instance.
Sometimes a set of parenthesis is needed to disambiguate declarations.
For example:
int *f(); // a function returning a pointer to int
int (*f)(); // a pointer to a function returning an int
Rather than listing exactly when and where using parenthesis is required and where it perhaps should be forbidden (because it is useless), the standard just says that they are allowed.
So you end up with the slightly confusing:
int a; // an int variable
int (b); // another int variable
With regards to this piece of code:
#include <iostream>
class CClass1
{
public:
void print() {
std::cout << "This should print first" << std::endl;
}
};
class CClass2
{
public:
void print() {
std::cout << "This should print second" << std::endl;
}
};
So someone asked an interesting question about having a "free pointer" (so to speak) which can point to multiple instances of different objects without having to create a new type of that object. The person had the idea that this pointer can be of type void * and since it is void, it can be made to point to any instance of an object and access the object's public properties.
The following solution was submitted:
int main() {
void *pClass(NULL);
((CClass1 *)(pClass))->print();
((CClass2 *)(pClass))->print();
std::cin.ignore();
return 0;
}
My question is why does the above work, but this doesn't:
int main() {
(CClass1 *FG)->print();
(CClass2 *FG)->print();
std::cin.ignore();
return 0;
}
Your first example exhibits undefined behavior, by calling a non-static member function via a pointer that doesn't point to a valid object. It only appears to work by accident, because the function in question just happens not to use this in any way.
Your second example is, quite simply, syntactically incorrect. I'm not even sure what you are trying to do there; the code makes no sense.