I have the following problem I want to be solved. I started out with a large class P, which I wanted to split up. Therefore a part of the functionality was moved to a new class Q. However, I do not seem to be able to make these two communicate properly. To make this a bit more visual, I made this toy example:
#include <iostream>
class Q {
public:
int* x_ptr;
Q(){ } // Is there any way to not have to write default constructors?
Q(int* x_ptr){
x_ptr = x_ptr;
}
void say_x(){
std::cout << *x_ptr << std::endl;
}
void change_x(){
*x_ptr += 1;
}
};
class P {
public:
Q q;
int x;
P(int x){
x = x;
q = Q(&x);
}
};
int main(){
P my_p = P(10);
my_p.q.say_x();
my_p.q.change_x();
std::cout << my_p.x << std::endl;
}
I want the class Q to be responsible for changing P.x. To do this, I thought that passing a reference to P.x to Q when it's created would work. However, this results in a segmentation fault. Is there a way to make Q able to access and modify x? The reason for this is that I eventually want to have a number of classes Q1, Q2 etc, which are all responsible for different operations on P.x, where P.x will be a more complicated data type than a simple int.
Your problems arise from the fact that your are using the same variable names for both function arguments and class members. Although this is allowed, it is (IMHO), very bad practice. If you want to keep the names, then you will need to add an explicit this-> in the functions where you need to distinguish between the two, otherwise your argument names will 'shadow' the class members.
So, your Q constructor, keeping the name-clashes, would need to be:
Q(int* x_ptr) {
this->x_ptr = x_ptr;
}
and your P constructor would be:
P(int x) {
this->x = x;
q = Q(&(this->x));
}
However, with simple name-changes to the arguments, this is much clearer:
Q(int* arg_x_ptr) {
x_ptr = arg_x_ptr;
}
//...
P(int arg_x) {
x = arg_x;
q = Q(&x);
}
As it stands, in your code, the line q = Q(&x); in the P constructor passes the address of the temporary object given as the argument, which causes a memory error (segmentation fault) when you later try to modify it.
Note: On your comment about not having to define a default constructor for Q - you can remove this provided you give the 'required' parameter when you declare/instatiate the q member in P:
class P {
public:
Q q{ nullptr }; // BEWARE: You can NEVER use this object as it stands!
int x;
//...
Related
[Global Scope]
myClass *objA, *objB, *obj;
int objnum;
I want to switch between objA and objB and assign them alternatively to obj, so in main() I have:
int main()
{
objA = new myClass(parameters...);
objB = new myClass(parameters...);
// start with objA;
objnum = 0;
obj = objA;
}
At some point a function is called that switches between the two objects:
void switchObjects()
{
if (++objnum > 1) objnum = 0;
obj = objnum == 0 ? objA : objB;
}
And in the function where I use the object, I have:
void doYourJob()
{
int res = obj->work();
}
Now the weird thing is that if I don't assign obj to either objA or objB, it still works. I would expect an exception, instead. Even if I do obj = NULL;, it still works! What's this voodoo?
OK, I could provide a different example that brings to the same result, without using a NULL pointer:
myClass *obj[2];
int objnum;
void switchObject()
{
if (++objnum > 1) objnum = 0;
}
void doYourJob()
{
res = obj[objnum]->work();
}
int main()
{
obj[0] = new myClass(parameters...);
obj[1] = new myClass(parameters...);
objnum = 0;
}
With the above code, regardless of the value of objnum, I still get both objects working together, even if I'm calling work() on only one instance.
And if I replace the function doYourJob() with this:
void doYourJob()
{
int res1 = obj[0]->work();
int res2 = obj[1]->work();
}
I always get the results doubled, as if I were calling the function work() twice on every object.
Consider a simpler example:
#include <iostream>
struct X
{
void foo() { std::cout << "Works" << std::endl; }
};
int main() {
X* x = nullptr;
x->foo();
}
With most compilers and on most platforms, this code will appear to work fine, despite having called foo on a null pointer. However, the behaviour is technically undefined. That is, the C++ language gives no restrictions about what might happen if you do this.
Why does it work? Well, calling a member function only requires knowing the type of the object it is being called on. We know that x points at an X, so we know what function to call: X::foo. In many cases, it may be difficult or even impossible to know if a pointer points at a real object, so the compiler just lets it happen. The body of the function, in this case, doesn't actually depend on the X object actually existing, so it just works. This isn't something you can depend on though.
I have a problem. I need to clone objects class containing pointers. An example of the problem is in the following code:
#include "stdafx.h"
#include <iostream>
#include <string.h>
#include <vector>
class CPoint
{
protected:
int m_x;
int m_y;
int *m_p;
public:
CPoint();
CPoint(int x, int y);
~CPoint();
CPoint* clone();
static CPoint* clone(CPoint& p);
int getX();
int getY();
void setX(int x);
void setY(int y);
void toString();
};
int CPoint::getX()
{
return m_x;
}
int CPoint::getY()
{
return m_y;
}
void CPoint::setX( int x )
{
m_x = x;
}
void CPoint::setY( int y )
{
m_y = y;
}
void CPoint::toString()
{
std::cout << "(" << m_x << ", " << m_y<< ", " << *m_p << ")" << std::endl;
}
CPoint::CPoint( int x, int y )
{
m_x = x;
m_y = y;
m_p = new int();
*m_p = x + y;
}
CPoint::CPoint()
{
m_p = new int();
*m_p = 1000;
}
CPoint* CPoint::clone()
{
CPoint *p = new CPoint();
*p = *this;
return p;
}
CPoint* CPoint::clone( CPoint& p )
{
CPoint *q = new CPoint();
*q = p;
return q;
}
CPoint::~CPoint()
{
if (m_p) {
delete m_p;
m_p = NULL;
}
}
int _tmain(int argc, _TCHAR* argv[])
{
CPoint *p1 = new CPoint(10, 20);
CPoint *p2 = new CPoint(30, 40);
p1->toString();
p2->toString();
CPoint *p3;
p3 = CPoint::clone(*p1);
p3->toString();
CPoint *p4;
p4 = p2->clone();
p4->toString();
p1->setX(50);
p1->setY(60);
p2->setX(80);
p2->setY(90);
p3->toString();
p4->toString();
delete p1;
delete p2;
delete p3;
delete p4;
int a;
std::cin >> a;
return 0;
}
The problem I have with the variable m_p. When clone objects p1 and p2 on p3 and p4, the memory addresses p1 and p3 are different but m_p address is the same. Obviously, when remove p1, p3 removal fails. With p2 and p4 is the same.
How I can clone a CPoint class object?
You seem to be applying the rules of some other Java like language to C++.
This is a fundamental problem and going to lead to all sorts of problems in the long run.
You need to learn the idioms of C++.
In C++ you want to use C++ strings (std::string) not the C-String interface.
#include <string.h> // C-Interface
// What you really want
#include <string> // C++ Interface
If your class contains a pointer then you are probably doing something wrong. RAW pointers should be wrapped in a smart pointer (or containers) to control their lifespan correctly. If you put a pointer into an business class you are breaking the separation of concerns principle.
class CPoint
{
protected:
int m_x;
int m_y;
int *m_p; // What is it supposed to be?
// Who owns it?
Since your class had a pointer it broke the rule of three.
If you wanted to manage the pointer in this class (and you don't (breaking separation of concerns)) then you should have implemented the rule of three (rule of five in C++11) (look it up). If you want to learn how handle a RAW pointer look here https://stackoverflow.com/a/1846409/14065
There is no need for a clone method. This is what the copy constructor is for. You are not writing a class that needs to be cloned (otherwise it would have had a virutal destructor). Your class is not polymorphic and will not be derived from. Thus a copy constructor will work perfectly.
CPoint* clone();
static CPoint* clone(CPoint& p);
// Copy constructor looks like this:
CPoint(CPoint const& rjs)
// Assignment operator looks like this:
CPoint& operator=(CPoint& rhs)
But non of this is required if correctly wrap your RAW pointer in an appropriate class. The compiler generated default versions of these methods will work fine.
Good way to completely destroy encapsulation.
int getX();
int getY();
void setX(int x);
void setY(int y);
To string! Poop. What you really want is a serialization method.
void toString();
// serializer look like this:
friend std::ostream& operator<<(std::ostream& stream, CPoint const& data)
{
// Convert CPoint (data) to the stream.
return stream;
}
In C++ we do not dynamically create objects unless we need to.
And here you do not need to. Creating local objects works better because their lifespan is guaranteed even in the presence of exceptions.
// Rather than dynamically creating them
CPoint *p1 = new CPoint(10, 20);
CPoint *p2 = new CPoint(30, 40);
// Just declare two local variables:
CPoint p1 = CPoint(10, 20);
CPoint p2(30, 40); // Alternative to the above but means the same.
// Much better to use operator<<
// Also shows the functions are badly named. You are not converting to string.
// but rather printing them to a stream.
p1->toString();
p2->toString();
std::cout << p1;
myFileStream << p2; // allows you to easily specify the actual stream.
Copy constructor work much better for copying an object
CPoint *p3;
p3 = CPoint::clone(*p1);
// If we were still using pointers.
CPoint* p3 = new CPoint(p1);
// But much nicer to not even use pointers
CPoint p3(p1);
Its usually a design mistake if you ever see manual call to delete in a function.
delete p1;
delete p2;
delete p3;
delete p4;
If you have pointers wrapping them in smart pointers (or container) like classes makes them exception safe to use. This is because for local objects the destructor is guaranteed to be called and thus your object will correctly deleted the pointer when it goes out of scope. Currently this code is not exception safe and will leak if an exception propagates passed them.
Small note: main() is special. If you don't specify a return value the compiler plants return 0; for you. If your application has no error state best to use this functionality as a sign to other developer that your code will always exit cleanly.
return 0;
I would re-write like this:
#include <iostream>
#include <string>
#include <vector>
class CPoint
{
protected:
int m_x;
int m_y;
std::vector<int> m_p;
public:
// If you don't explicitly initialize m_x and m_y them
// they will have indeterminate (random) values.
CPoint() : m_x(0), m_y(0) {m_p.push_back(1000);}
CPoint(int x, int y) : m_x(x), m_y(y) {m_p.push_back(x + y);}
int getX() { return m_x;}
int getY() { return m_y;}
void setX(int x) { m_x = x;}
void setY(int y) { m_y = y;}
friend std::ostream& operator<<(std::ostream& stream, CPoint const& d)
{
return stream << "(" << d.m_x << ", " << d.m_y<< ", " << d.m_p[0] << ")" << std::endl;
}
};
int main(int argc, char* argv[])
{
CPoint p1(10, 20);
CPoint p2(30, 40);
std::cout << p1 << p2;
CPoint p3(p1);
std::cout << p3;
CPoint p4(p2);
std::cout << p4;
p1.setX(50);
p1.setY(60);
p2.setX(80);
p2.setY(90);
std::cout << p1 << p2 << p3 << p4;
int a;
std::cin >> a;
}
In this example is an integer but may be any type. The question I had was like to clone an object that contains a pointer to another type.
I believe that there are basically two situations here: you want the containing object to own the pointed-to object; or you don't want the containing object to own the pointed-to object.
Let's start with non-owning. What's the tool that C++ provides to represent non-owning pointers? Well, regular pointers are non-owning. And how do you copy a regular pointer? You do nothing. You let the compiler deal with it, generating the correct copy constructor that you can use at will (and while you're at it, let the compiler generate a destructor as well).
And what about owning? What's the tool for owning pointers? Well, for most cases you don't even need a pointer for that: just store a value directly and, again, let the compiler generate the correct copy constructor (and a destructor too!). In the example provided int m_p; would work nicely.
There is an annoyance in this situation when polymorphic base classes are involved: copying may cause slicing. Does C++ provide a tool for this situation? Sadly, it doesn't. You have to write it by hand. But do yourself a favour and don't mix these concerns with the rest of the class (Single Responsibility Principle).
Write a reusable class (bonus points: make it a template) that owns a single pointer, cleans it up on destruction, and performs a polymorphic copy (a common idiom involves a virtual clone function) in the copy constructor. Then put a value of that reusable class in your CPoint and... you guessed it! Let the compiler generate the correct copy constructor.
In addition to shallow-copying the immediate data members m_x and m_y, you need to deep-copy the pointer member m_p. Since you haven't shown the constructor for this class or what m_p really points to, I'm going to assume that m_p points to the first element of an array of int. Deep-copying this entails:
Instantiate a new array of int that is the same (or larger) size as the original array
Copy each element from the original array to the new array
Set m_p in the cloned object to point to the first element of this new array
An example of how this might be done:
CPoint* CPoint::clone(CPoint& rhs)
{
CPoint* ret = new CPoint;
ret->m_x = rhs.m_x;
ret->m_y = rhs.m_y;
size_t m_p_count = /* somehow determine the size of rhs.m_p */;
ret->m_p = new int[m_p_count];
std::copy(&rhs.m_p[0], &rhs.m_p[m_p_count], ret->m_p);
return ret;
}
A few notes about your code:
You would be better off using a vector<int> instead of a raw pointer to an array of int.
Barring #1, you should be using smart pointers instead of raw pointers
I don't see any way in the code above to determine the size of the array. This would be easy if you used a vector<int> -- just call vecctor<int>::size(). You need to know the size of the array in order to make a copy of it, obviously.
A clone() type function is generally only useful when making a copy of a polymorphic object via a base class pointer. Since your class, and your useage of it, does not fall in to this category, a clone() function is not the right way to go in the first place. Consider using a copy constructor and a copy assignment operator instead, and don't forget to also implement a destructor. Better still, avoid all of this stuff altogether and follow the Rule of Zero.
You must reallocate memory for all pointers within CPoint and copy their data into new memory. In your case you have to do following operation:
CPoint clone()
{
CPoint p;
p = *this;
p.m_p = new int();
*p.m_p = *m_p;
return p;
}
You have to ask yourself: Does each instance of your object "own" the object it points to, or do they all refer to a common object owned by something else?
When you have a case of ownership, each instance must point to an individual copy. That means that you don't have to copy the pointer, you have to create a clone of the object it points to and assign this new object to the pointer of the copy.
Assuming that m_p points to only one integer (and not a whole array), cloning can be done like this:
CPoint* CPoint::clone()
{
CPoint* cloned = new CPoint(m_x, m_y);
if (m_p)
{
cloned->m_p = new int;
*cloned->m_p = *m_p;
}
return cloned;
}
Note that such a member pointer has the sole purpose of adding the additional possibility of having a NULL-value - which can have a separate meaning.
Note also that the following has to be done to avoid memory leaks and heap corruption:
The copy constructor and assignment operator have to be "disabled" (declared private)
The destructor must delete m_p.
I've probably become a bit to used to Java and am finding this harder than it should be. Heres what I have.
myObject[0] = new item1(this);
class item1
{
private:
int x;
int y;
public:
item1( passedPointer* pOne )
{
x = 5;
y = 5;
}
int returnX() { return x; }
int returnY() { return y; }
}
Then in another method I thought I could just say:
void check()
{
int y = item1.returnY();
int x = item1.returnX();
}
But I am getting the common error: a nonstatic member reference must be relative to a specific object.
There is only one instance of this class item1, what would be the best way to do this? This is just a simplified fragment of what I'm actually doing, not the actual code.
Item1 is a class. You have to create an instance of it before you can access its non-static members. Try looking here for some basic information.
void check(){
int y = item1.returnY;
int x = item1.returnX;
}
This would also be incorrect in Java, since neither returnX nor returnY are statics, you need an object on which to apply the operation, and you also need the parenthesis of the method call:
void check() {
item1 i;
int y = i.returnY();
int x = i.returnX();
}
Perhaps implementing the Singleton pattern would not do you harm, since you want only one instance of the object. You could declare the object as global or static to a function too, then get the values.
Then again, you could also declare the functions as static, and add another one to initialize the static values of the variables which need to be returned by those methods. There are a lot of solutions to this depending on your situation which can not be fully grasped by the short amount of code you have pasted.
You created an instance of class item1 with the line
myObject[0] = new item1(this);
Unlike JAVA, in C++ there are pointers and new returns a pointer to the object (so myObject[0] is a pointer to the instance) so you need the -> operator. To activate the method you should write:
myObject[0]->returnX();
If you wish to have only one instance than implement the class as a singleton.
Suppose I have a class:
class test {
public:
void print();
private:
int x;
};
void test::print()
{
cout<< this->x;
}
and I have these variable definitions:
test object1;
test object2;
When I call object1.print() this happens to store address of object1 and so I get x from object1 printed and when I call object2.print() this happens to store address of object2 and I get x from object2 printed. How does it happen?
Each non-static member function has an implicit hidden "current object" parameter that is exposed to you as this pointer.
So you can think that for
test::print();
there's some
test_print( test* this );
global function and so when you write
objectX.print();
in your code the compiler inserts a call to
test_print(&objectX);
and this way the member function knows the address of "the current" object.
You can think of the this pointer being an implicit argument to the functions. Imagine a little class like
class C {
public:
C( int x ) : m_x( x ) { }
void increment( int value ) {
m_x += value; // same as 'this->m_x += value'
}
int multiply( int times ) const {
return m_x * times; // same as 'return this->m_x * times;'
}
private:
int m_x;
};
which allows you to write code like
C two( 2 );
two.increment( 2 );
int result = two.multiply( 3 );
Now, what's actually happening is that the member functions increment and multiply are called with an extra pointer argument, pointing to the object on which the function is invoked. This pointer is known as this inside the method. The type of the this pointer is different, depending on whether the method is const (as multiply is) or not (as is the case with increment).
You can do something like it yourself as well, consider:
class C {
public:
C( int x ) : m_x( x ) { }
void increment( C * const that, int value ) {
that->m_x += value;
}
int multiply( C const * const that, int times ) const {
return that->m_x * times;
}
private:
int m_x;
};
you could write code like
C two( 2 );
two.increment( &two, 2 );
int result = two.multiply( &two, 3 );
Notice that the type of the this pointer is C const * const for the multiply function, so both the pointer itself is const but also the object being pointed to! This is why you cannot change member variables inside a const method - the this pointer has a type which forbids it. This could be resolved using the mutable keyword (I don't want to get side-tracked too far, so I'll rather not explain how that works) but even using a const_cast:
int C::multiply( int times ) const {
C * const that = const_cast<C * const>( this );
that->m_x = 0; // evil! Can modify member variable because const'ness was casted away
// ..
}
I'm mentioning this since it demonstrates that this isn't as special a pointer as it may seem, and this particular hack is often a better solution than making a member variable mutable since this hack is local to one function whereas mutable makes the variable mutable for all const methods of the class.
The way to think about it is that this is simply a pointer to the memory for whichever object you're currently working with. So if you do obj1.print(), then this = &obj1;. If you do obj2.print(), then this = &obj2;.
this has different values for different objects
Each instance of class test gets it's own copy of member variable x. Since x is unique for each instance, the value can be anything you want it to be.
The variable this, refers to the instance to which it is associated. You don't have to use the variable 'this'. You could just write:
void test::print()
{
cout << x;
}
Using C++ I built a Class that has many setter functions, as well as various functions that may be called in a row during runtime.
So I end up with code that looks like:
A* a = new A();
a->setA();
a->setB();
a->setC();
...
a->doA();
a->doB();
Not, that this is bad, but I don't like typing "a->" over and over again.
So I rewrote my class definitions to look like:
class A{
public:
A();
virtual ~A();
A* setA();
A* setB();
A* setC();
A* doA();
A* doB();
// other functions
private:
// vars
};
So then I could init my class like: (method 1)
A* a = new A();
a->setA()->setB()->setC();
...
a->doA()->doB();
(which I prefer as it is easier to write)
To give a more precise implementation of this you can see my SDL Sprite C++ Class I wrote at http://ken-soft.com/?p=234
Everything seems to work just fine. However, I would be interested in any feedback to this approach.
I have noticed One problem. If i init My class like: (method 2)
A a = A();
a.setA()->setB()->setC();
...
a.doA()->doB();
Then I have various memory issues and sometimes things don't work as they should (You can see this by changing how i init all Sprite objects in main.cpp of my Sprite Demo).
Is that normal? Or should the behavior be the same?
Edit the setters are primarily to make my life easier in initialization. My main question is way method 1 and method 2 behave different for me?
Edit: Here's an example getter and setter:
Sprite* Sprite::setSpeed(int i) {
speed = i;
return this;
}
int Sprite::getSpeed() {
return speed;
}
One note unrelated to your question, the statement A a = A(); probably isn't doing what you expect. In C++, objects aren't reference types that default to null, so this statement is almost never correct. You probably want just A a;
A a creates a new instance of A, but the = A() part invokes A's copy constructor with a temporary default constructed A. If you had done just A a; it would have just created a new instance of A using the default constructor.
If you don't explicitly implement your own copy constructor for a class, the compiler will create one for you. The compiler created copy constructor will just make a carbon copy of the other object's data; this means that if you have any pointers, it won't copy the data pointed to.
So, essentially, that line is creating a new instance of A, then constructing another temporary instance of A with the default constructor, then copying the temporary A to the new A, then destructing the temporary A. If the temporary A is acquiring resources in it's constructor and de-allocating them in it's destructor, you could run into issues where your object is trying to use data that has already been deallocated, which is undefined behavior.
Take this code for example:
struct A {
A() {
myData = new int;
std::cout << "Allocated int at " << myData << std::endl;
}
~A() {
delete myData;
std::cout << "Deallocated int at " << myData << std::endl;
}
int* myData;
};
A a = A();
cout << "a.myData points to " << a.myData << std::endl;
The output will look something like:
Allocated int at 0x9FB7128
Deallocated int at 0x9FB7128
a.myData points to 0x9FB7128
As you can see, a.myData is pointing to an address that has already been deallocated. If you attempt to use the data it points to, you could be accessing completely invalid data, or even the data of some other object that took it's place in memory. And then once your a goes out of scope, it will attempt to delete the data a second time, which will cause more problems.
What you have implemented there is called fluent interface. I have mostly encountered them in scripting languages, but there is no reason you can't use in C++.
If you really, really hate calling lots of set functions, one after the other, then you may enjoy the following code, For most people, this is way overkill for the 'problem' solved.
This code demonstrates how to create a set function that can accept set classes of any number in any order.
#include "stdafx.h"
#include <stdarg.h>
// Base class for all setter classes
class cSetterBase
{
public:
// the type of setter
int myType;
// a union capable of storing any kind of data that will be required
union data_t {
int i;
float f;
double d;
} myValue;
cSetterBase( int t ) : myType( t ) {}
};
// Base class for float valued setter functions
class cSetterFloatBase : public cSetterBase
{
public:
cSetterFloatBase( int t, float v ) :
cSetterBase( t )
{ myValue.f = v; }
};
// A couple of sample setter classes with float values
class cSetterA : public cSetterFloatBase
{
public:
cSetterA( float v ) :
cSetterFloatBase( 1, v )
{}
};
// A couple of sample setter classes with float values
class cSetterB : public cSetterFloatBase
{
public:
cSetterB( float v ) :
cSetterFloatBase( 2, v )
{}
};
// this is the class that actually does something useful
class cUseful
{
public:
// set attributes using any number of setter classes of any kind
void Set( int count, ... );
// the attributes to be set
float A, B;
};
// set attributes using any setter classes
void cUseful::Set( int count, ... )
{
va_list vl;
va_start( vl, count );
for( int kv=0; kv < count; kv++ ) {
cSetterBase s = va_arg( vl, cSetterBase );
cSetterBase * ps = &s;
switch( ps->myType ) {
case 1:
A = ((cSetterA*)ps)->myValue.f; break;
case 2:
B = ((cSetterB*)ps)->myValue.f; break;
}
}
va_end(vl);
}
int _tmain(int argc, _TCHAR* argv[])
{
cUseful U;
U.Set( 2, cSetterB( 47.5 ), cSetterA( 23 ) );
printf("A = %f B = %f\n",U.A, U.B );
return 0;
}
You may consider the ConstrOpt paradigm. I first heard about this when reading the XML-RPC C/C++ lib documentation here: http://xmlrpc-c.sourceforge.net/doc/libxmlrpc++.html#constropt
Basically the idea is similar to yours, but the "ConstrOpt" paradigm uses a subclass of the one you want to instantiate. This subclass is then instantiated on the stack with default options and then the relevant parameters are set with the "reference-chain" in the same way as you do.
The constructor of the real class then uses the constrOpt class as the only constructor parameter.
This is not the most efficient solution, but can help to get a clear and safe API design.