In Java you can simply return this to get the current object. How do you do this in C++?
Java:
class MyClass {
MyClass example() {
return this;
}
}
Well, first off, you can't return anything from a void-returning function.
There are three ways to return something which provides access to the current object: by pointer, by reference, and by value.
class myclass {
public:
// Return by pointer needs const and non-const versions
myclass* ReturnPointerToCurrentObject() { return this; }
const myclass* ReturnPointerToCurrentObject() const { return this; }
// Return by reference needs const and non-const versions
myclass& ReturnReferenceToCurrentObject() { return *this; }
const myclass& ReturnReferenceToCurrentObject() const { return *this; }
// Return by value only needs one version.
myclass ReturnCopyOfCurrentObject() const { return *this; }
};
As indicated, each of the three ways returns the current object in slightly different form. Which one you use depends upon which form you need.
One of the main advantages of return by reference in classes is the ability to
easily chain functions.
Suppose that your member function is to multiply a particular member of your class.
If you make the header and source files to keep the information of the class and the definition of the member function separately, then,
the header file myclass.h would be:
#ifndef myclass_h
#define myclass_h
class myclass{
public:
int member1_;
double member2_;
myclass (){
member1_ = 1;
member2_ = 2.0;
}
myclass& MULT(int scalar);
myclass* MULTP(double scalar);
};
#endif
and the source file: myclass.cpp would be:
myclass& myclass::MULT(int scalar){
member1_ *= scalar;
return *this;
}
myclass* myclass::MULTP(double scalar){
member2_ *= scalar;
return this;
}
If you initialize an object called obj, the default constructor above sets member1_ equal to 1:
Then in your main function, you can do chains such as:
myclass obj;
obj.MULT(2).MULT(4);
Then member1_ would now be 8. Of course, the idea might be to chain different functions,
and alter different members.
In the case you are using the return by pointer, the first call uses the object,
and any subsequent call will treat the previous result as a pointer, thus
obj.MULTP(2.0)->MULTP(3.0);
Because the return type is void, i.e.: you declare that you don't return anything. Change it to myclass* to return this change to myclass & to return reference to the class through *this.
Related
I'm trying to wrap a Python PyObject* in an Object class.
In Python, everything is a PyObject*.
A list is a PyObject*, and each item in the list is itself a PyObject*.
Which could even be another list.
etc.
I'm trying to allow fooList[42] = barObj style syntax by means of a Proxy pattern (here).
Now that I have that working, I want to extend it so that fooList[42] can be used as an Object. Specifically I want to be able to handle...
fooList[42].myObjMethod()
fooList[42].myObjMember = ...
Object has a lot of methods, and currently fooList[42].myObjMethod() is going to first resolve fooList[42] into a Proxy instance, say tmpProxy, and then attempt tmpProxy.myObjMethod().
This means I would have to do
void Proxy::myObjMethod(){ return wrapped_ob.myObjMethod(); }
i.e. manually relay each of Object's methods through Proxy, which is ugly.
I can't see any perfect solution (see the above linked answer), but I would be happy to use:
fooList[42]->myObjMethod()
... as a compromise, seeing as -> can be overloaded (as opposed to . which cannot).
However, I can't find any documentation for overloading operator->.
My best guess is that it must return a pointer to some object (say pObj), and C++ will invoke pObj->whatever.
Below is my attempted implementation. However, I'm running into a 'taking the address of a temporary object of type Object' warning.
I have, within my Object class:
const Object operator[] (const Object& key) const {
return Object{ PyObject_GetItem( p, key.p ) };
}
NOTE that 'const Object&' runs into 'taking the address of a temporary object of type Object' warning.
class Proxy {
private:
const Object& container;
const Object& key;
public:
// at this moment we don't know whether it is 'c[k] = x' or 'x = c[k]'
Proxy( const Object& c, const Object& k ) : container{c}, key{k}
{ }
// Rvalue
// e.g. cout << myList[5] hits 'const Object operator[]'
operator Object() const {
return container[key];
}
// Lvalue
// e.g. (something = ) myList[5] = foo
const Proxy& operator= (const Object& rhs_ob) {
PyObject_SetItem( container.p, key.p, rhs_ob.p );
return *this; // allow daisy-chaining a = b = c etc, that's why we return const Object&
}
const Object* operator->() const { return &container[key]; }
// ^ ERROR: taking the address of a temporary object of type Object
};
The idea is to allow myList[5]->someMemberObj = ... style syntax.
myList[5] resolves as a Proxy instance, which is wrapping an Object (the sixth element of myList). Let's call it myItem.
Now I want someProxy->fooFunc() or someProxy->fooProperty to invoke myItem.fooFunc() or myItem.fooProperty respectively.
I'm running into a 'taking the address of a temporary object of type Object' warning.
If you can change Object, you may add
class Object {
public:
// other code
const Object* operator -> () const { return this; }
Object* operator -> () { return this; }
};
And for your Proxy
Object operator->() { return container[key]; }
So, for example
myObj[42]->myFoo = ...
is mostly equivalent to
Proxy proxy = myObj[42];
Object obj = proxy.operator ->();
Object* pobj = obj.operator ->(); // so pobj = &obj;
pobj->myFoo = ...
I find the Proxy class that you wrote as an example a bit confusing so i took the liberty to change it a little:
Here is a simple example:
//object with lots of members:
class my_obj
{
public:
std::string m_text;
void foo()
{
std::cout << m_text << std::endl;
}
void bar(std::string t)
{
m_text = t;
}
};
//proxy object
class proxy_class
{
private:
friend class CustomContainer;
my_obj* px;
proxy_class(my_obj * obj_px)
:px(obj_px)
{
}
proxy_class() = delete;
proxy_class(const proxy_class &) = delete;
proxy_class& operator =(const proxy_class &) = delete;
public:
my_obj* operator ->()
{
return px;
}
};
//custom container that is the only one that can return proxy objects
class CustomContainer
{
public:
std::map<std::size_t, my_obj> stuff;
proxy_class operator [](const std::size_t index)
{
return proxy_class(&stuff[index]);
}
};
example usage:
CustomContainer cc;
cc[0]->foo();
cc[0]->bar("hello world");
cc[0]->foo();
As a design consideration the proxy class should be create in a controlled environment so constructors are removed from preventing miss-usage.
CustomContainer has to only return proxy_class with a reference to my_obj so it can use anything, std::map, std::vector, etc
After several hours of coaxing coliru, I have a working testcase.
Please refer to: https://codereview.stackexchange.com/questions/75237/c11-proxy-pattern-for-supporting-obidx-someobjmember-type-acc
Many thanks to Jarod, for supplying the correct syntax and understanding for -> overload.
So I have a class called MusicComposer that has an AudioSignal object as a data member called music. Music is non-const. However, I need to return music as a const AudioSignal in a method called getMusic.
In the source file:
const AudioSignal& MusicComposer::getMusic(){
}
music is declared as:
AudioSignal music;
^ this is in the header file.
I declare music as non-const because music needs to be changed before it is returned by the getMusic method. However, I can't figure out for the life of me how to return a const version of it. How can I return a const version of music?
C++ can automatically change mutable to const for you whenever. No biggie. It's going the other way that's hard.
return music;
If you really want to be explicit you could do this, but it's wierd code, and wierd is bad.
return static_cast<const AudioSignal&>(music);
Also, Cyber observed that getter methods themselves are usually const, which lets them be called even when MusicComposer is const.
const AudioSignal& MusicComposer::getMusic() const {
^^^^^
Take a look in this example:
#include <iostream>
class A { // declare class A
int integer;
};
class B { // declare class B
public:
const A& get() { // get() will return a const ref
return a; // here it is returning the ref of data member a
}
private:
A a;
};
int main() {
A a;
B b;
a = b.get();
return 0;
}
As mentioned by potatoswatter,
const is a property of the expression accessing the object, not the object itself
Why do the following usage give me an error: Undefined referrence to "Environment::self"
So below is my test case and the class is just below it, header and cpp:
Test:
Environment bla;
bla=Environment::CTE;
if(bla==1){
printf("CTE!");
}else if(bla==Environment::PPE){
printf("NO: its ppe");
}
Header:
class Environment{
public:
enum{CTE, PTE, PPE, LOCALHOST};
static int self;
bool operator==(const int& rhs)const;
Environment& operator=(const int &rhs);
};
And CPP:
#include "Environment.h"
bool Environment::operator==(const int& rhs)const{
if (this->self ==rhs)
return true;
return false;
}
Environment& Environment::operator=(const int &rhs) {
if (this->self != rhs) {
this->self=rhs;
}
return *this;
}
You've declared self as static. This means:
You must define it somewhere. That is, put int Environment::self; into exactly one .cpp file. This fill fix your "Unresolver reference" linker error.
Being static means there's just one instance of self for the entire class. Therefore, accessing it through this->self is not necessary, and is actually confusing. It seems to imply each instance of class Environment has its own copy, but that is in fact not true.
If you want each instance of Enviornment to have its own value of self, simply drop the static keyword from self's declaration.
The pseudo code for what I want to do is:
function<bool(int)> getFunc(type) // get a function depending on what type is passed
problem is the function to return must be declared as static? As a result, I can't access object properties. So I need to pass them into the function? Thus, the original function to return might look like:
bool func1(int)
bool func2(int)
Now needs to be injected with other objects/arguments it need to run ...
bool func1(int, Class1)
bool func2(int, Class2)
So how do I define the return type of getFunc? Or maybe theres a better way?
UPDATE
In the above, func* functions are actually: has*(). eg.
hasStmtsUsing(variable)
hasVariablesUsed(stmt)
And to determine if the condition is true, it uses an object eg. uses. Then there are other similar has*() functions like hasStmtsModifying(variable) that uses an object modifies. uses and modifies are objects of different types, and originally, they are object members, thus dont need to be passed in. Now since the functions are static, they need to be passed in.
While writing this, I am thinking what I need is some kind of dependency injector? Maybe I pass in DI and call DI.getX() functions?
Maybe I'm misunderstanding something, but isn't all you need to use a memberfunction where you bind() the first parameter?
class X {
bool f1(int);
bool f2(int);
};
X x;
function<bool(int)> f = bind(&X::f1, &x);
Here's an example of how it can be done with lambdas in C++11:
#include <cassert>
#include <functional>
#include <iostream>
struct Class1 {
};
struct Class2 {
};
bool func1(int,Class1)
{
return true;
}
bool func2(int,Class2)
{
return false;
}
inline std::function<bool(int)> getFunc(Class1 obj1)
{
return [=](int x){ return func1(x,obj1); };
}
inline std::function<bool(int)> getFunc(Class2 obj2)
{
return [=](int x){ return func2(x,obj2); };
}
int main(int,char**)
{
Class1 obj1;
std::function<bool(int)> f1 = getFunc(obj1);
Class2 obj2;
std::function<bool(int)> f2 = getFunc(obj2);
assert(f1(0)==true);
assert(f2(0)==false);
return 0;
}
This question already has answers here:
When should I make explicit use of the `this` pointer?
(12 answers)
Closed 6 years ago.
What is purpose of this keyword. Doesn't the methods in a class have access to other peer members in the same class ? What is the need to call a this to call peer methods inside a class?
Two main uses:
To pass *this or this as a parameter to other, non-class methods.
void do_something_to_a_foo(Foo *foo_instance);
void Foo::DoSomething()
{
do_something_to_a_foo(this);
}
To allow you to remove ambiguities between member variables and function parameters. This is common in constructors.
MessageBox::MessageBox(const string& message)
{
this->message = message;
}
(Although an initialization list is usually preferable to assignment in this particular example.)
Helps in disambiguating variables.
Pass yourself as a parameter or return yourself as a result
Example:
struct A
{
void test(int x)
{
this->x = x; // Disambiguate. Show shadowed variable.
}
A& operator=(A const& copy)
{
x = copy.x;
return *this; // return a reference to self
}
bool operator==(A const& rhs) const
{
return isEqual(*this, rhs); // Pass yourself as parameter.
// Bad example but you can see what I mean.
}
private:
int x;
};
Consider the case when a parameter has the same name as a class member:
void setData(int data){
this->data = data;
}
Resolve ambgiguity between member variables/functions and those defined at other scopes
Make explicit to a reader of the code that a member function is being called or a member variable is being referenced.
Trigger IntelliSense in the IDE (though that may just be me).
The expression *this is commonly used to return the current object from a member function:
return *this;
The this pointer is also used to guard against self-reference:
if (&Object != this) {
// do not execute in cases of self-reference
It lets you pass the current object to another function:
class Foo;
void FooHandler(Foo *foo);
class Foo
{
HandleThis()
{
FooHandler(this);
}
};
Some points to be kept in mind
This pointer stores the address of
the class instance, to enable pointer
access of the members to the member
functions of the class.
This pointer is not counted for
calculating the size of the object.
This pointers are not accessible for
static member functions.
This pointers are not modifiable
Look at the following example to understand how to use the 'this' pointer explained in this C++ Tutorial.
class this_pointer_example // class for explaining C++ tutorial
{
int data1;
public:
//Function using this pointer for C++ Tutorial
int getdata()
{
return this->data1;
}
//Function without using this pointer
void setdata(int newval)
{
data1 = newval;
}
};
Thus, a member function can gain the access of data member by either using this pointer or not.
Also read this to understand some other basic things about this pointer
It allows you to get around members being shadowed by method arguments or local variables.
The this pointer inside a class is a reference to itself. It's needed for example in this case:
class YourClass
{
private:
int number;
public:
YourClass(int number)
{
this->number = number;
}
}
(while this would have been better done with an initialization list, this serves for demonstration)
In this case you have 2 variables with the same name
The class private "number"
And constructor parameter "number"
Using this->number, you let the compiler know you're assigning to the class-private variable.
For example if you write an operator=() you must check for self assignment.
class C {
public:
const C& operator=(const C& rhs)
{
if(this==&rhs) // <-- check for self assignment before anything
return *this;
// algorithm of assignment here
return *this; // <- return a reference to yourself
}
};
The this pointer is a way to access the current instance of particular object. It can be used for several purposes:
as instance identity representation (for example in comparison to other instances)
for data members vs. local variables disambiguation
to pass the current instance to external objects
to cast the current instance to different type
One more purpose is to chaining object:
Consider the following class:
class Calc{
private:
int m_value;
public:
Calc() { m_value = 0; }
void add(int value) { m_value += value; }
void sub(int value) { m_value -= value; }
void mult(int value) { m_value *= value; }
int getValue() { return m_value; }
};
If you wanted to add 5, subtract 3, and multiply by 4, you’d have to do this:
#include
int main()
{
Calc calc;
calc.add(5); // returns void
calc.sub(3); // returns void
calc.mult(4); // returns void
std::cout << calc.getValue() << '\n';
return 0;
}
However, if we make each function return *this, we can chain the calls together. Here is the new version of Calc with “chainable” functions:
class Calc
{
private:
int m_value;
public:
Calc() { m_value = 0; }
Calc& add(int value) { m_value += value; return *this; }
Calc& sub(int value) { m_value -= value; return *this; }
Calc& mult(int value) { m_value *= value; return *this; }
int getValue() { return m_value; }
};
Note that add(), sub() and mult() are now returning *this. Consequently, this allows us to do the following:
#include <iostream>
int main()
{
Calc calc;
calc.add(5).sub(3).mult(4);
std::cout << calc.getValue() << '\n';
return 0;
}
We have effectively condensed three lines into one expression.
Copied from :http://www.learncpp.com/cpp-tutorial/8-8-the-hidden-this-pointer/
Sometimes you want to directly have a reference to the current object, in order to pass it along to other methods or to store it for later use.
In addition, method calls always take place against an object. When you call a method within another method in the current object, is is equivalent to writing this->methodName()
You can also use this to access a member rather than a variable or argument name that "hides" it, but it is (IMHO) bad practice to hide a name. For instance:
void C::setX(int x)
{
this->x = x;
}
For clarity, or to resolve ambiguity when a local variable or parameter has the same name as a member variable.
It also allows you to test for self assignment in assignment operator overloads:
Object & operator=(const Object & rhs) {
if (&rhs != this) {
// do assignment
}
return *this;
}
It also allows objects to delete themselves. This is used in smart pointers implementation, COM programming and (I think) XPCOM.
The code looks like this (excerpt from some larger code):
class counted_ptr
{
private:
counted_ptr(const counted_ptr&);
void operator =(const counted_ptr&);
raw_ptr_type _ptr;
volatile unsigned int _refcount;
delete_function _deleter;
public:
counted_ptr(raw_ptr_type const ptr, delete_function deleter)
: _ptr(ptr), _refcount(1), _deleter(deleter) {}
~counted_ptr() { (*_deleter)(_ptr); }
unsigned int addref() { return ++_refcount; }
unsigned int release()
{
unsigned int retval = --_refcount;
if(0 == retval)
>>>>>>>> delete this;
return retval;
}
raw_ptr_type get() { return _ptr; }
};
The double colon in c++ is technically known as "Unary Scope resolution operator".
Basically it is used when we have the same variable repeated for example inside our "main" function (where our variable will be called local variable) and outside main (where the variable is called a global variable).
C++ will alwaysexecute the inner variable ( that is the local one).
So imagine you want to use the global variable "Conundrum" instead the local one just because the global one is expressed as a float instead of as an integer:
#include <iostream>
using namespace std;
float Conundrum=.75;
int main()
{
int Conundrum =75;
cout<<::Conundrum;
}
So in this case the program will use our float Conundrum instead of the int Conundrum.