I have run into a strange problem. When i try to write a function that returns a pointer to a subclass which i swap for a different instance of that subclass i get the "error C2106: '=' : left operand must be l-value" error.
Tthe problems is at the one->getMe() = two; line :
class subClass{};
class someClass{
public:
subClass * pointer;
someClass(){
pointer = new subClass;
}
subClass * getMe(){
return pointer;
}
};
int main(){
someClass * one = new someClass;
subClass * two = new subClass;
one->getMe() = two;
}
I'm a bit new to c++ so the problem might be horrible simple. Any help is much appreciated.
The pointer that you return from the function is a copy of the pointer in the object. It is a temporary, you cannot assign to it. Even if you could assign to it, it would do no good, because it is no longer connected to the pointer in your object. If you want to be able to assign to the object's pointer after returning it from the function, you want to return the pointer by reference.
subClass *& getMe() {
return pointer;
}
You should also may want to consider adding a const overload in order to work on const objects. It might look like this:
subclass * const & getme() const {
return pointer;
}
The line
one->getMe() = two;
Is trying to assign the pointer at two to one->getMe(). But one->getMe() returns a temporary copy which you cannot assign to. If you want to return the pointer by reference and thus be able to change it then you can use the signature
subClass *& getMe();
as others have suggested.
That being said, you're exposing the inner workings of a class for all and sundry to see and modify, in particular pointers to objects on the heap which may or may not be deallocated correctly which is unwise.
Related
Consider a simple class:
class MyInt {
public:
MyInt();
MyInt(const char *num);
};
I want to intergrate reference counting design pattern in to the class, which means i need to keep track of how much pointers point to an instance of this class. I need to implement it in this class only or create a different class and inherit it.
Given this example code i want to clear any allocated memory of the program:
int main() {
MyInt*a = new MyInt("10");
a = new MyInt("20");
delete a;
return 0;
}
My Tries
I tried operator oveloading of '=' and adding referenceCount member:
MyInt &MyInt::operator=(const MyInt* right) {
MyInt*left = this;
*this = right;
left->referenceCount -= 1;
if (left->referenceCount == 0) {
delete (left);
}
return *this;
}
But this does not work because we assign pointer of the class to another pointer.
Also tried to override the new and delete operators but can't seem to make it work and keep track of the number of pointer to an instance.
As it seems i need to implement four things: copy constructor, operator new, operator delete and operator =.
How can i effectivly keep track of the pointers and clear unpointed memory automaticly?
std::shared_ptr does exactly this. From the ref:
Manages the storage of a pointer, providing a limited
garbage-collection facility, possibly sharing that management with
other objects. [...] Once all shared_ptr objects that share ownership
over a pointer have released this ownership, the managed object is
deleted.
so I suggest you use this instead.
a is a pointer, so assigning to a will not involve MyInt::opterator= in any way. There is no way to detect when a pointer to T is assigned to by overloading T's operators. To do this, you would need to design a class type that behaves like a pointer. Then you could properly track when the pointer might leak an object and properly delete it. Fortunately for you, the standard library already provides this class. It's std::shared_ptr. Here is your example modified to use std::shared_ptr :
#include <memory>
struct InfInt {
InfInt(const char *) {}
};
int main()
{
auto a = std::make_shared<InfInt>("10");
a = std::make_shared<InfInt>("20"); // the previous `a` is deleted
// The object pointed to by `a` is automatically deleted when
// the last reference to it goes out of scope
return 0;
}
I was wandering through the code of Sequitur G2P and found a really strange line of code:
public:
...
const Node *childrenEnd() const { return (this+1)->finalized.firstChild_; }
I know that this is a pointer to the current object, and since it is a pointer, the operation is perfectly legal, but what does this+1 actually refer to?
Presumably this is part of an array, so this+1 would refer to the next object in that array.
this is simply a pointer which refers to this object. Since it's a pointer, you can apply pointer arithmetic and even array indexing.
If this object is an element in an array, this+1 would point to the next object in the array.
If it's not, well it's just going to treat whatever is at that memory the same as this object, which will be undefined behaviour unless it is the same type.
As it is NLP it makes sense to optimize memory management. I assume you find overloaded new/delete methods as well.
The this+1 construct assumes all objects reside in an array. The name 'childrenEnd' of the method indicates it returns a pointer to an address of the end of the children of the current node.
Thus you are looking at an implementation of a tree structure. All siblings are adjacent and their children as well.
"this + 1" in C++ class means:
if the "this" object is a member of another object it will point to the address of the parent's object next variable declared just after the "this" object variable:
Example:
class B
{
public:
void* data()
{
return this + 1;
}
};
class A
{
public:
B m_b;
char m_test;
};
int main(int argc, char* argv[])
{
A a;
a.m_test = 'H';
void* p = a.m_b.data();
char c;
memcpy(&c, p, sizeof(char));
return 0;
}
c is equal 'H'.
Long story short it allows to access to parent's class data without passing parent's pointer to the child class. In this example this + 1 point to the m_test member of the class A.
Actually, there is a case, when this thing could be used. I don't recommend to use this method, but it certainly works.
I believe, in NLP code it was used something like that:
when you want your object to behave as a collection (an array etc) to use it similarly as an array with something range-based etc, you can do this trick:
struct Obj {
...
Obj* begin() { return this; }
Obj* end() { return this+1; }
...
}
Now, you can use this object in, for example, range-based for-loops...
Sometimes all that is necessary... but just even there you'd better use "nullptr" or even do refactoring than to use this trick.
I have a class that contains a pointer. I want to keep the user of the class from accessing the address of the pointer (so they can't set it to another address, delete it, or what-not). However, I would like the user to be able to modify the pointer data (or member data if it's not POD) as well as call the pointer's methods (assuming it has any).
Is there any way of returning a pointer or reference that allows you to change the data that a pointer points to without being able to change the pointer value itself?
So:
class A
{
public:
int Value;
void Method();
};
class Wrapper
{
public:
Wrapper()
{
Pointer = new A;
}
// Method that somehow would give access to the object without
// Allowing the caller to access the actual address
A* GetPointer()
{
return Pointer;
}
private:
A* Pointer;
};
int main()
{
Wrapper foo;
foo.GetPointer()->Value = 12; // Allowed
foo.GetPointer()->Method(); // Allowed
A* ptr = foo.GetPointer(); // NOT Allowed
delete foo.GetPointer(); // NOT Allowed
return 0;
}
I realize I could modify member data with getters and setters, but I'm not sure what to do about the methods (pass a method pointer maybe?) and I'd like to know if there is a better way before I accept a solution that I personally think looks messy.
It's not possible. The whole reason why ->Value is legal is because the expression to the left is a (smart) pointer to A*.
Obviously, with a non-smart pointer you already have your A* right there. Since raw pointers are not user-defined types, you cannot mess with the overload resolution.
With a smart pointer, (*ptr).Value has to work. That means you have to return a A& from operator* which in turn means that &(*ptr) gets you the traw pointer from a smart pointer.
There's even std::addressof for classes that try to block operator&.
You could make a getter That returns a reference to the object, ex:
A &GetObject()
{
return *Pointer;
}
This allows full access to the pointed-to object without providing access to the pointer itself at all.
I know Class *cls is a pointer, and Class &cls takes the address, but what is
void fucction1( Class *&cls)
If I have Class c, what should I pass to function1()?
Thanks!
Besides, what James explained in his response, let me add one more important point to it.
While you can write Class* & (reference to pointer) which is perfectly valid in C++ only, you cannot write Class& * (pointer to reference), as you cannot have a pointer to a reference to any type. In C++, pointer to reference is illegal.
ยง8.3.2/4 from the language specification reads,
There shall be no references to
references, no arrays of references,
and no pointers to references.
If I have Class c, what should I pass
to function1()?
You can write your calling code like this:
Class *ptrClass;
//your code; may be you want to initialize ptrClass;
function1(ptrClass);
//if you change the value of the pointer (i.e ptrClass) in function1(),
//that value will be reflected here!
//your code
For a type T, T* is a pointer to an object of type T, so Class* is a pointer to a Class object.
For a type T, T& is a reference to an object of type T, so putting them together, Class*& is a reference to a pointer to a Class object.
Class c;
Class* c_ptr = &c;
function1(c_ptr);
Would work. But note that rvalue-references is only possible with C++0x which most compilers haven't fully implemented them. Thus the following wouldn't work:
Class c;
function1(&c);
As said, a reference to a pointer to Class.
you pass a Class * to the function
the function may change the pointer to a different one
This is a rather uncommon interface, you need more details to know what pointers are expected, and what you have to do with them.
Two examples:
Iteration
bool GetNext(Classs *& class)
{
if (class == 0)
{
class = someList.GetFirstObject();
return true;
}
class = somePool.GetObjectAbove(class); // get next
return class != 0;
}
// Use for oterating through items:
Class * value = 0;
while (GetNext(value))
Handle(value);
Something completely different
void function (Class *& obj)
{
if (IsFullMoon())
{
delete obj;
obj = new Class(GetMoonPos());
}
}
In that case, the pointer you pass must be new-allocated, and the pointer you receive you need to pass either to function again, or be delete'd by you.
I have an interesting question about C++ pointers.
You probably will think that I have to change my design, and avoid
doing what I am doing, and you are probably right.
But let's assume that I have a good reason to do it my way.
So this is the situation. I have a C++ class TestClass, and I have a pointer A of this type:
TestClass* A = new TestClass();
Among other things TestClass has this function:
void TestClass::Foo(){
TestClass* B = new TestClass();
...
}
This function creates object B of the same type and populates it with some data.
At the end of this function, I want pointer A to point at object B.
Anywhere outside this function it would look like A=B; inside this function
it could look like this = B
But as you know you cannot reassign "this" pointer.
Possible solutions:
Copy the memory:
memcpy(this, B, sizeof(TestClass));
This method works correctly. The function copies each bit of object B into object A.
Problem: if TestClass is a big object(and it is), it creates significant overhead in performance for multiple Foo calls.
Return a B pointer from the function and do something like this
Temp = A;
A=A->Foo();
freeMemory(Temp);
But this code looks stupid, and it makes function Foo very hard to use.
So the question is, how I can do this = B from inside a member function, without copying whole objects?
Use an extra level of indirection. Your TestClass can have a pointer that points to a class that contains all of its data.
class TestClass
{
private:
TestClassData* m_data;
};
void TestClass::Foo()
{
TestClassData* B = new TestClassData();
...
delete m_data;
m_data = B;
}
Just make sure your operator== returns true if the contents of m_data are equal.
how i can do this = B
You cannot.
One of the working solutions:
memcpy(this, B, sizeof(TestClass));
this method working correctly.
If TestClass is not a POD, this function doesn't work. You can't memcpy objects with virtual functions, for example. You'll blow away the vtable.
Inside of your function, you can do
*this = B;
Which make pretty the same copy operation.
Or you could also declare
Foo(TestClass &X);
And reassign X address inside.
You can't. this is defined by the standard as a TestClass * const.
To realize why, think about this code:
int main() {
TestClass A;
A.Foo();
return 0;
}
A is on the stack. How do you make an object on the stack 'refer' to something else?
The problem is that many pointers, not just A, can point to the old object. The this pointer is not A, although A contains a copy of it. The only way to do it is 1. reassign A, or 2. make a new pointer type that adds a level of indirection to your object so you can replace it without anyone knowing.
What you are doing is not good.
First off, you have function Foo that will:
Create and generate a new class
Reassign an existing class to the new class
So, why not just change the existing class into the class you want?
That said, you could make Foo static and take "take this manually":
void Foo(TestClass*& this)
{
delete this;
this = // ...
}
But that's equally nasty as your other solutions. We probably need more context to give you the best solution.
I'm pretty sure that you should look at smart pointers as a way to solve this problem. These essentially add an extra level of indirection (without changing the syntax clients use), and would allow you so change the actual object pointed to without informing the client.