So say I was using this to create an object:
MyClass myObject;
and I had the function inside of the class to act upon the object. So one way could be using parameters, like this:
MyClass foo(MyClass a) {
return a;
}
Seems simple. But is there a way so I can use myObject.foo() and it would still return a even though I'm not using it as a parameter? One example could be some of the methods in std::string - you can use std::string.swap(), using the object for the swap() function.
Is there a way, or am I being stupid?
First off, keep in mind that you original code of
MyClass foo(MyClass a) {
return a;
}
does not actually return a. It returns a copy of a, which itself is a copy of whatever instance of MyClass you passed into foo. If you want to pass in a given object, act on it and return it, you need to use references, like so
MyClass & foo(MyClass & a) {
return a;
}
This will ensure that the a you get back from a call to foo is the exact same object you passed into it.
Additionally, an object can always return a reference to itself in one of its members...
class MyClass {
MyClass & foo() { return *this; }
}
This is especially useful in classes where you might want to chain a large number of operations together...
MyClass my = MyClass().foo().bar("Hello").baz(5);
Inside every member function is a magic secret parameter, which is a pointer to the object who's method was called, and the parameter's name is this.
MyClass& foo() { //returns reference to existing MyClass instead of making copies
this->print(); //call a different member
return *this; //return a reference to itself. Common for `operator=` and such.
}
Inside a class's (non-static) member function, you can use *this to name the object the function was called on.
So:
MyClass MyClass::foo() {
return *this;
}
(Notice that function returns a copy of the object. If you don't want a copy, use a reference as in #Jherico's answer.)
Related
I was wondering if the following is correct usage of a std::shared_ptr.
All I want to do with the originally created pointer is add it onto the vector on class A,
which will be later on retrieved
class A
{
public:
void AddToVec(std::shared_ptr<B> b)
{
myVec_.push_back(b);
}
std::vector<std::shared_ptr<B>> GetVec()
{
return myVec_;
}
private:
std::vector<std::shared_ptr<B>> myVec_;
}
Then on main, a pointer is created and passed with the following way
int main()
{
A a;
std::shared_ptr<B> ptr = std::make_shared<B>();
a.AddToVec(std::move(ptr));
}
Is the usage of the std::move correct on the main function?
Is it okay to simply create the std::shared_ptr on main and move ownership using the AddToVec function?
Is the usage of the std::move correct on the main function?
Yes, it is correct. If you do not use the std::move, it will also compile; however, it increases the reference count of std::shared_ptr.
Is it okay to simply create the shared ptr on main and move ownership using the AddToVec function?
It is correct in the sense, you do not want to increment the reference count of the std::shared_ptr.
The same you need inside AddToVec, as the b is lvalue reference inside the function scope. Therefore, you need to explicitly std::move into the myVec_ as follows:
void AddToVec(std::shared_ptr<B> b)
{
myVec_.push_back(std::move(b));
}
Also note that the GetVec will return each time a copy of the member myVec_, which you might not want. Therefore, you might need one or both the following
// non-const reference to the member
std::vector<std::shared_ptr<B>>& GetVec()
{
return myVec_;
}
// const reference to the member
const std::vector<std::shared_ptr<B>>& GetVec() const /* noexcept */
{
return myVec_;
}
Is it possible to make a local copy of 'this' pointer in a class function? The purpose is to then modify the copy and return it, without modifying 'this' itself.
The function looks like this:
classA classA::function() {
classA newObject = //where I need help;
//modification of newObject
return newObject;
}
You can create copies from this as long your class provides a copy constructor by simply dereferencing the this pointer as needed:
classA classA::function() {
return *this;
// ^^^^^ Simply dereference and let the compiler do the copying
}
Ensure your class declaration follows the Rule of 3/5/zero!
I created a member function that returning reference to object.
I can do it like:
class Foo {
Foo &ref(){
return *this;
}
}
ref returning object by look up this pointer.
Is there any way else to return object without using this?
EXPLAIN the reason:
The reason I don't want to use this is: the pointer occupy 4B in stack whereas the reference share the same memory
It sounds like you don't like this and you don't want to dereference any pointers. How about:
class Foo {
private:
int dummy;
public:
Foo& ref() {
return reinterpret_cast<Foo&>(dummy);
}
};
static_assert(std::is_standard_layout<Foo>::value,
"Foo must be standard-layout!");
Because Foo is a standard-layout class and dummy is its first non-static data member and there are no base classes, the address of dummy is the same as that of the containing Foo.
Needless to say, this is a very silly way to return a reference to an object and I can't see any possible justification for doing it this way. Not wanting to write return *this; is like wanting to add two integers without using +. It just makes no sense at all.
Is it possible to use the this pointer to assign the data from a calling object to one declared in a const member function? Something like:
(assuming I've already built SomeClass)
void func() const
{
SomeClass object1;
object1 = *this;
}
int main()
{
SomeClass object2;
object2.func();
return 0;
}
I know the above function is pointless. I'm just wondering if it's a legal assignment using *this.
This code is fine, so long as SomeClass has a copy assignment operator. The const on the member function declares that you will not change the state of the object: func() doesn't do this, so it is legal code. There are ways of subverting const if you try hard enough, however, this is not one of them.
Here is part of my code:
class A
{
public:
void init(classB& pObject);
classB& _pObject;
}
void classA::init(classB& pObject)
{
_pObject = pObject;
}
class B
{
public:
void init();
}
void classB::init()
{
classA* pClassA = new classA;
pClassA->init(&this);
}
I got 2 problems after compile:
_pObject = pObject;: No viable overloaded '='
pClassA->init(&this);: Address expression must be an lvalue or a function designator
I'm getting confused about these problems... How can I fix that?
First, there is a typo in the question. I assume that A and classA refer to the same class, ditto for B and classB.
1) One of the few differences between a reference and a pointer is that you cannot assign a different value to a reference once it's been initialised. So you just cannot assign to _pObject, though you can initialise it in the initialisation list of the constructor for class A:
classA::classA(classB& object) : _pObject(object) // Correct
{
// _pObject = object; on the other hand, this would be incorrect
}
2) &this is the address of this, but you actually want a reference to the value pointed to by this. You need to use *this instead. Though we have already seen that there is no way to make function classA::init work with your current class design. If you really want to change the value of _pObject after the object has been constructed, you need to make it a classB* instead of a classB&.
1) You should use *this in this context, as &this has the type of ClassB**, not ClassB&;
2) You can only initialize you reference member-variables in constructor:
classA::classA(classB& b) : _pObject(b)
{
}
(BTW I suppose that you ommitted delete statement just for brevity)