const newString& newString::operator=(const newString& rightStr)
{
if(this!=&rightStr)
{
delete[] strPtr;
strLength=rightStr.strLength;
strPtr = newChar[strLength+1];
strcpy(strPtr,rightStr.strPtr);
}
return* this;
}
I know it avoids self copy, but what does "this" keyword refer to? I mean I thought it was rightStr but then why would it chechk if its equal to itself?
In a non-static class method, the this keyword is defined by the C++ language as a pointer to the object that the current class method was invoked on.
In your case, this refers to the newString object on the left side of the assignment statement that invoked newString::operator=. For example, in the below code:
newString strSrc, strDest;
strDest = strSrc;
Inside of newString::operator=, this is a pointer to the strDest object, and rightStr is a reference to the strSrc object.
"This" keyword can be used to pass current object as a parameter to another method or it can be used to refer current class instance variable.
Related
If i define a function like this
std::string& returnstring(std::istringstream &ist)
{
std::string temp;
std::getline(ist,temp);
return temp;
}
and if i use this temp which is passed by reference to another function like this
void displaystring(std::string &temp)
{
std::cout<<temp;
}
would the string temp still be in scope when i pass it by reference to displaystring function?
The scope of a variable is the scope where it is declared. std::string temp; is declared within the body of the function returnstring, therefore that function body is the scope of the variable. It is an automatic variable, and therefore its lifetime ends at the end of its scope and it is automatically destroyed.
The returned reference will be invalid (i.e. it is a dangling reference). If you attempt to access the non-existing object through the invalid reference, then the behaviour of the program will be undefined.
To fix the function, a simple solution is to return a value instead.
Nope since the temp variable is local to the returnstring function and once the code is out of the retuernstring function the temp variable is no longer valid.
If at all you want to send the reference and get the answer then better option is to send the argument by reference as below,
void copyLineAsString(std::istringstream &ist, std::string& tempString)
{
std::getline(ist,tempString);
return;
}
I have few other suggestions to your code for the good coding practice,
Never use the '&' for the return type / return a variable by reference. Use camel casing or _ separator for the function names(Ex returnString or return_string).
No. The scope of temp is limited to the block where it is declared. Because you declared it on stack (you didn't use the keyword new), the variable temp will be destroyed the moment you exit the function.
The only way to keep the variable would be to have the value of temp be copied to a variable outside the function. For example, this would work:
std::string returnstring(std::istringstream &ist)
{
std::string temp;
std::getline(ist,temp);
return temp;
}
Because the return value is a copy rather than a reference, you could then do
std::string returned_string = returnstring(ist);
And have the value of temp be copied into a newly declared variable that could be used for your displaystring function.
In general, I would avoid declaring variables inside a function that you will need outside the scope of the function. Instead, return by value whenever you are returning variables built inside of the function (not recommended for large arrays and objects, however).
this is the reference variable which refers to the current class object which has called it. it has scope only inside the class and the same as the lifetime of the object which called it.
I'm trying to keep a reference to a pointer of a different class in my class. I'm trying to see if there is a way to do this without having to define it in the ctor. I cannot make a copy, as I'm using that specific pointer returned to do other things.
class MyClass {
private:
OtherClassPtr &m_ptr_ref;
public:
MyClass();
public:
void MyFunction() {
m_ptr_ref = otherClassPtr->GetPtrRef();
if(!m_ptr_ref)
return;
}
};
A reference needs to be initialized at the point of declaration, and cannot change to refer to a different object during its lifetime. Thus you need to set it in the constructor.
An alternative is to store a pointer. I think of a reference as a pointer with nicer syntax, though the different syntax gives it a different semantic meaning; it acts like the object that it refers to, and so has the same value and the same address as that object. Most relevant to your question, the assignment operator works like assignment to the object, rather than a pointer. This is the reason it cannot change referent.
You can keep a pointer to the pointer:
OtherClassPtr* m_ptr_ref;
/* ... */
m_ptr_ref = &otherClassPtr->GetPtrRef();
An alternative is to use std::reference_wrapper, but that is nothing more than a fancy pointer, and I don't see the advantage over using a pointer.
Here I am taking an example of overloading the increment operator:
class Digit
{
int m_digit;
public:
Digit (int value) //constructor
{
m_digit = value;
}
Digit& operator++();
int ret_dig (){return m_digit;}
};
Digit& Digit::operator++()
{
if (m_digit == 9)
m_digit = 0;
else ++m_digit;
return *this;
}
int main ()
{
Digit my_dig (5);
++my_dig;
return 0;
}
I have been told that local variables can't be returned. Isn't "this" a local variable? Here is what I think:
A pointer of type Digit is attached to the member function (overloaded operator function). When compiler sees the line ++my_dig, that is an instance of Digit class, it calls the member function. The address of the instance my_dig is passed as argument to the function and there is a hidden "const Digit*" named "this" to catch the argument. "this" is dereferenced(implicitly) to access m_digit, that is a member variable of class Digit. All the increment or wrapping is done inside the function and a reference to dereferenced "this" is then returned to the caller. Yes, this is the point to my confusion. If "this" is a local variable of type const Digit*, shouldn't it contain garbage when returned because "this" is going out of scope where the block ends haaa?
this is an implicit parameter to all member functions which points to the object itself -- which has a strictly longer lifetime than the method. The parameter itself is a local variable, but the object that it points to exists outside the method.
In this case the object is created on the first line of your main function and then lives until the main method exits. Thus the object is safely alive throughout the call to operator++!
The *this is the object and not a local variable. Any temporary objects which the compiler deems necessary to allocate, such as those needed to complete a expression, has a lifetime to the end of the expression.
This becomes interesting for objects which has a destrctor, as the destructor run not when the individual parts of the expression is completed, but when the entire expression completes -- hence your *this variable will survive just sufficiently long to complete what is needed.
Have a look at this question for deeper discussion
this is a local variable, but it is initialized by &my_dig when it enters the method. The value of &my_dig has the same lifetime as my_dig, which ends at the end of the main block. So while this goes out of scope, the value of this is still valid.
I have to make google test for some function wrote by someone else, and I've got situation which I never have before. See pseudocode below:
typedef boost::shared_ptr<CSomeClass> CSomeClass_sh_ptr;
CSomeClass_sh_ptr getSomething(int A)
{
if(A>3)
{
return CSomeClass_sh_ptr();
}
CSomeClass_sh_ptr pointerToCSomeClass = otherPointerToCSomeClass;
return pointerToCSomeClass;
}
So my question is - what does
CSomeClass_sh_ptr()
or
boost::shared_ptr<CSomeClass>()
mean?
In your context, CSomeClass_sh_ptr() is a default constructed instance of CSomeClass_sh_ptr. In other words, a default constructed boost::shared_ptr<CSomeClass>.
Note that boost::shared_ptr<SomeClass> is not a pointer. It is a type that manages a pointer. When default constructed, its managed pointer is NULL or nullptr.
Your misconception is that you consider boost::share_ptr<CSomeClass> a pointer, while it is actually a class managing a pointer to CSomeClass, therefore boost::share_ptr<CSomeClass>() denotes a construction of object of that class.
The name of a type, followed by a (), means to create a temporary of that type, value initialized. In your case, as others have pointed out, the type is an instantiation of a class template, thus a class. To value initialize a class is to call its default constructor, if it has one, or to zero-initialize it, if it has no constructors. (boost::shared_ptr has a default constructor, so it gets called). If you actually had a pointer, to value initialize it would be to zero-initialize it, which would result in a null pointer. (The default constructor of boost::shared_ptr mimics this aspect of pointer behavior; its default constructor creates a shared pointer which behaves like a null pointer.)
I'm converting a C++ program to C#, but this part has me confused. What does return *this mean?
template< EDemoCommands msgType, typename PB_OBJECT_TYPE >
class CDemoMessagePB : public IDemoMessage, public PB_OBJECT_TYPE
{
(...)
virtual ::google::protobuf::Message& GetProtoMsg() { return *this; }
}
How would it translate into C#?
this means pointer to the object, so *this is an object. So you are returning an object ie, *this returns a reference to the object.
Watch out that if you try to use return *this; on a function whose return type is Type and not Type&, C++ will try to make a copy of the object and then immediately call the destructor, usually not the intended behaviour. So the return type should be a reference as in your example.
In your particular case, you are returning the reference to 'this', since the return type of the function is a reference (&).
Speaking of the size of returned memory, it is the same as
virtual ::google::protobuf::Message* GetProtoMsg() { return this; }
But the usage at call time differs.
At call time, you will call store the return value of the function by something like:
Message& m = GetProtoMsg();
Using a pointer we can directly access the value stored in the variable which it points to. To do this, we simply have to precede the pointer's identifier with an asterisk (*), which acts as dereference operator and that can be literally translated to "value pointed by".
You are just returning a reference to the object. this is a pointer and you are dereferencing it.
It translates to C# return this; in the case that you are not dealing with a primitive.
Like in C# this is an implicit pointer to the object you are currently using.
In your particular case, as you return a reference & to the object, you must use *this if you want to return the object you are currently working on.
Don't forget that a reference takes the variable itself, or in case of a pointer (this), the object pointed to (*this), but not the pointer (this).