I tried copying a pointer to another by using a method inside the class and the this pointer as follows. I am giving the entire test code so that it is clear what is going on.
class test {
private:
int x;
public:
void setx(int x);
int getx(void);
void copy(test *temp);
};
void test::setx(int x) {
this->x = x;
}
int test::getx(void) {
return this->x;
}
void test::copy(test *temp) {
this = temp;
}
And I access this method from the main as follows:
int main() {
test a;
a.setx(4);
cout << a.getx()<<endl;
test *b = new test;
b->setx(4);
cout << b->getx()<<endl;
test *c;
c=b;
cout << c->getx()<<endl;
test *d;
d->copy(b);
cout << d->getx()<<endl;
}
However it gives the following error
In member function ‘void test::copy(test*)’:
error: lvalue required as left operand of assignment
All the other method involving the this pointer works fine except for the copying part. Am i doing some elementary mistake in using the this pointer?
You cannot overwrite this. The this pointer is a constant, so you're not allowed to change it. And what would that mean anyway? You can't change the object that you're in. You can change the values within that object, but not the object itself.
You need to copy other objects by value (by what is stored in the object), not by pointer.
Also, you shouldn't have a function called copy; that's what copy constructors and copy assignment operators are for.
You cannot modify the this pointer. You can however modify *this:
void test::copy(test *temp)
{
*this = *temp;
}
Also, you should rename the data member or the parameter, so you don't need this->:
class test
{
int m_x;
public:
void setx(int x)
{
m_x = x;
}
what is test::copy supposed to do?
Clearly you cant assign a different address to your current object. So it is invalid.
if this is supposed to initialize the current object with the values of some other object then it should look like this:
void test::copy(test *temp) {
this->x = temp->getX();
}
Related
Class A
{
public:
A();
A(int x , int y);
Private:
int x;
int y;
}
Class B
{
public:
B();
A getApointerobject() const;
Private:
A *APointerObject;
int main()
{
B bObj;
cout << bObj.getApointerobject(); //i overloaded the << so that i can //output B objects but it crushes
}
//Class B implementation (This is where i struggle)
A getApointerobject() const {
return *getApointerobject;
}
In B::getApointerobject() you call it recursively. You should change to
A getApointerobject() const {
return *APointerObject;
}
Is B::APointerObject initialized before you call getApointerobject() method?
In getApointerobject you are trying to return the address of the method getApointerobject itself. I guess you code is not even compiling right now?
I guess you want to return your APointerObject
A B::getApointerobject() const {
return *this->APointerObject;
}
But be advised: Built in types, including simple pointers don't have a default constructor. So, since you don't initialise APointerObject in class Bs constructor, you would use a wild pointer. Which means you program would crash at runtime or worse (undefined behavior)
class A{
private:
int a;
public:
const int &ref = a;
};
int main() {
A obj;
obj.a = 20; // error cause private
obj.ref = 30; // not private but const so ERROR
return 0;
}
I'm trying to make a member variable accessible but read only through the interface. Currently I've tried this approach and it seems to compile fine. I made a const reference to my original variable int a and made it public. Is there anything that's wrong with this practice that I might be missing out? Or is this example safe and sound to use for practical purposes?
Nothing wrong with providing a member function with const correctness applied (and I've used that too and intend to do so always), but I'm asking is there any thing wrong with this way if I have to provide a variable that is only read-only.
Thankyou :)
class A{
private:
int a;
public:
const int &ref = a;
};
is there any thing wrong with this way if I have to provide a variable that is only read-only
There are at least a couple drawbacks with this design decision for class A.
1: Class Size
Also as Dieter Lücking mentions in a
comment:
increasing the size of the class, needlessly
2: Copy Semantics
It breaks the compiler generated copy assignment operator. For example, the following code behavior is generally desirable but doesn't work.
A obj1;
// ...
A obj2;
// make changes to 'obj2'
// Update 'obj1' with the changes from 'obj2'
obj1 = obj2; // This copy doesn't work!
More information:
Should I prefer pointers or references in member data?
Assignment operator with reference class member
Thinking in C++, 2nd ed. Volume 1 ©2000 by Bruce Eckel, 11: References & the Copy-Constructor
There are certain rules when using references:
A reference must be initialized when it is created. (Pointers can be initialized at any time.)
Once a reference is initialized to an object, it cannot be changed to refer to another object. (Pointers can be pointed to another object at any time.)
You cannot have NULL references. You must always be able to assume that a reference is connected to a legitimate piece of storage.
It may be possible to implement a custom assignment operator but that's more code to maintain (i.e., another drawback in my opinion).
#include <iostream>
class A
{
private:
int a;
public:
explicit A(int value) : a(value) {}
A& operator=(const A& other)
{
a = other.a;
return *this;
}
const int& ref = a;
};
int main()
{
A obj1(10);
std::cout << "1: " << obj1.ref << "\n";
A obj2(20);
std::cout << "2: " << obj2.ref << "\n";
obj1 = obj2;
std::cout << "1: " << obj1.ref << "\n";
return 0;
}
The idiomatic way to address this issue is to use a proper accessor function.
class A {
private:
int a;
public:
int getA() const { return a; }
};
The standard way to do this in C++ is by making the actual member private but including a public 'getter' method for the interface, as below:
class A{
private:
int a;
public:
int get_a() const { return a; }
A() : a(20) {}
};
int main() {
A obj;
int n = obj.get_a(); // n = 20
return 0;
}
The user cannot set the value of A::a but can use A::get_a to retrieve its value.
In C++, if i type:
int x=5;
int &y=x;
then y will act as an alias for the memory location where original x is stored and this can be proven/tested by printing the memory location of both, x and y
the output of a similar program is below:
x is at location: 0x23fe14
y is at location: 0x23fe14
But what about classes?
when a member function is declared with return type as a reference and the function uses the this pointer, what is the function actually returning?
for example:
#include <iostream>
class simple
{
int data;
public:
// ctor
simple():
data(0)
{}
// getter function
int& getter_data()
{ return this->data; }
// modifier functions
simple& add(int x=5)
{ this->data += x;
return *this;
}
simple& sub(int x=5)
{ this->data -= x;
return *this;
}
};
int main()
{ simple obj;
obj.add().sub(4); ////////// how & why is it working? /////////
std::cout<<obj.getter_data();
getchar();
}
why is it possible to execute the command in highlighted line?
what kind of data is obj.add() returning to the sub()?
When your member-function returns simple& initialized with *this (*this being an instance of simple) the semantics are the same as your own "reference example"; a reference is initialized with an instance of that type.
You are initializing the returned reference with the object itself.
The below snippets are semantically equivalent:
obj.add ().sub (4);
simple& ref = obj.add ();
ref.sub (4); // `ref` is really `obj`,
// the address of `ref` and `obj` are the same
what kind of data is obj.add() returning to the sub()?
obj.add() is returning a reference to the obj instance.
The text "returning to the sub()" is not making sense at all.
However, in your case, the reference to your object is very similar to a plain pointer to your object, and often it is a good metapher.
Hi I want to call an objects function in other function but i can't. Why ?
class class1
{
private:
int var;
public:
class1(int x);
void functionO();
};
class1::class1(int x)
{
var = x;
}
void class1::functionO()
{
cout<<"text";
}
void Callfunction()
{
object1->function0();
}
int main()
{
class1 *object1;
object1 = new class1(x);
Callfunction();
}
Compilator says that
'object1' : undeclared identifier
It seems logical but how can i call that objects function within a function ?
In this code:
void Callfunction()
{
object1->function0();
}
object1 is out-of-scope. That is, the compiler doesn't know about anything named object1 from within the scope of CallFunction().
Note that even if you had defined CallFunction after main(), this would still be true. All variables are local to the scope in which they are declared.
One option is to make object1 a global, and I'm sure that you will be advised to do this. But please don't. Global variables introduce state to your program, and along with it a host of other nasty problems that are hard to fix without tearing your program apart. Don't get in to the habit of using global variables to fix all manner of scoping issues. You will regret it.
Rather, why not just pass a class1 pointer to CallFunction()? Better yet, pass a reference.
void CallFunction(class1& obj1)
{
obj1.function0();
}
int main()
{
class1 *object1;
object1 = new class1(x);
Callfunction(*object1);
}
Your problem has nothing to do with the declaration order (before or after doesn't matter). Your object1 is a local variable of main. This means that it isn't visible outside of main, unless you explicitely pass it to the function needing it or store a pointer to it in a global variable (but please don't). To solve your problem you should therefore pass your object to Callfunction:
void Callfunction(class1& object1)
{
object1.function0();
}
int main()
{
class1 object1(x);//<-- This asumes that you have actually defined x
//somewhere, otherwise replace it with an actual value
Callfunction(object1);
}
Note that I took the liberty of clearing up the unneeded indirection (and the memory leak) by constructing the object on the stack instead of on the heap.
Pass your object as (reference) parameter to your function:
class class1
{
private:
int var;
public:
class1(int x);
void function0();
};
class1::class1(int x)
: var(x) // Note: Use member initializer lists
{}
void class1::function0()
{
std::cout << "text, var = " << var << std::endl;
}
void Callfunction(class1& object)
{
object.function0();
}
int main()
{
class1 object1(10);
class1 object2(42);
Callfunction(object1);
Callfunction(object2);
}
Expected output:
text, var = 10
text, var = 42
NOTE
The declaration order also matters, you might need to use a forward declaration when class1 is declared after the compiler sees Callfunction().
Suppose you have a class with a private pointer to an array. How can you use a getter to access (or effectively copy the data) so you can access it in a different variable.
class MyClass
{
private:
double *x;
public:
myClass();
virtual ~MyClass();
double* getX() const;
void setX(double* input);
};
MyClass::MyClass()
{
double foo[2];
double * xInput;
foo[0] = 1;
foo[1] = 2;
xInput = foo;
setX(xInput);
}
void MyClass::setX(double * input)
{
x = input;
}
double * MyClass::getX() const;
{
return x;
}
int main()
{
MyClass spam(); // Construct object
double * bar = spam.getX(); // This doesn't work
}
In this case, bar[0] and bar[1] are equal to jibberish: -9.2559631349317831e+061.
MyClass spam(); // Construct object
That does not construct an object, that declares a function called spam that takes no arguments and returns a MyClass. This default constructs an object:
MyClass spam; // Construct object
For more information google the most vexing parse.
Update: As #Mark Ransom pointed out, there is another problem with your code. In your constructor you create an array, and then set x to point to such array. However the array lifetime ends once the constructor finishes execution, so further access to x would crash (if you are lucky enough).
Just a guess, the program is crashing or showing the wrong output. This is because the constructor is setting a pointer to a local array, which leaves scope and gets destroyed at the end of the constructor.
That should probably be *bar instead of bar[0].