Trigger cast operator on use of the dot operator - c++

I have a class something like this:
template<typename T>
class wrapper
{
public:
operator const T & () const
{
return value;
}
private:
T value;
};
I then use it with a struct like this:
struct point { float x; float y; };
//...
wrapper<point> myPoint;
std::cout << myPoint.x;// error: no member x or whatever.
I'm wondering if there's a way to allow this without having to do ((point)myPoint).x. I know that I can overload the -> operator but I'd prefer not to since its supposed to "pretend" to be a non-pointer.

You can achieve something similar with -> instead of .:
template<typename T>
class wrapper
{
public:
operator const T & () const // will this still be needed now?
{
return value;
}
T* operator->() { return &value; }
T const* operator->() const { return &value; }
private:
T value;
};
And then:
struct point { float x; float y; }
//...
wrapper<point> myPoint; // this needs to be initialised!
std::cout << myPoint->x;

You cannot make your wrapper class pretend to be a real class the way you described. The main reason is that member selection (.) operator cannot be overloaded.

Related

C++ override member access operator for template class and return by reference

Is it possible to override the -> operator in template class and return something by reference?
I saw this post: Overloading member access operators ->, .*
And there is an example of overriding -> and return by reference, but I can't get this to work with templates. Here's a small example of what I'm trying to achieve:
#include <iostream>
using namespace std;
class A
{
public:
void do_something()
{
cout << "Hey there";
}
};
template<class T>
class Ref
{
public:
Ref(T* ptr)
{
objPtr = ptr;
}
// this is another alternative, but I don't want to write Get() every time I want to access the object
T& get() { return *objPtr; }
template <class T>
Ref<T>& operator->() const { return *objPtr; }
// doesn't work either
//T& operator->() const { return *objPtr; }
// this works as expected, but I really MUST return by reference
//T* operator->() const { return objPtr; }
private:
T* objPtr;
};
int main()
{
A myObj;
Ref<A> ref(&myObj);
// error C2675: unary '->': 'Ref<A>' does not define this operator or a conversion to a type acceptable to the predefined operator
ref->do_something();
return 0;
}
How can this be done?
If you return a reference, you can't use it in ref->do_something(); which requires a pointer. You'd have to use this cumbersome method:
ref.operator->().do_something();
Instead return a pointer - and make it a T* (or const T*), not a Ref<T>*.
Example:
#include <iostream>
class A {
public:
void do_something() {
std::cout << "Hey there\n";
}
};
template<class T>
class Ref {
public:
Ref(T& ptr) : objPtr(&ptr) {} // taking a T& but storing a pointer
const T* operator->() const { return objPtr; }
T* operator->() { return objPtr; }
private:
T* objPtr;
};
int main() {
A myObj;
Ref<A> ref(myObj);
ref->do_something();
}

Friend class read only access C++ [duplicate]

Whoopee, not working on that socket library for the moment. I'm trying to educate myself a little more in C++.
With classes, is there a way to make a variable read-only to the public, but read+write when accessed privately? e.g. something like this:
class myClass {
private:
int x; // this could be any type, hypothetically
public:
void f() {
x = 10; // this is OK
}
}
int main() {
myClass temp;
// I want this, but with private: it's not allowed
cout << temp.x << endl;
// this is what I want:
// this to be allowed
temp.f(); // this sets x...
// this to be allowed
int myint = temp.x;
// this NOT to be allowed
temp.x = myint;
}
My question, condensed, is how to allow full access to x from within f() but read-only access from anywhere else, i.e. int newint = temp.x; allowed, but temp.x = 5; not allowed? like a const variable, but writable from f()...
EDIT: I forgot to mention that I plan to be returning a large vector instance, using a getX() function would only make a copy of that and it isn't really optimal. I could return a pointer to it, but that's bad practice iirc.
P.S.: Where would I post if I just want to basically show my knowledge of pointers and ask if it's complete or not? Thanks!
Of course you can:
class MyClass
{
int x_;
public:
int x() const { return x_; }
};
If you don't want to make a copy (for integers, there is no overhead), do the following:
class MyClass
{
std::vector<double> v_;
public:
decltype(v)& v() const { return v_; }
};
or with C++98:
class MyClass
{
std::vector<double> v_;
public:
const std::vector<double>& v() const { return v_; }
};
This does not make any copy. It returns a reference to const.
While I think a getter function that returns const T& is the better solution, you can have almost precisely the syntax you asked for:
class myClass {
private:
int x_; // Note: different name than public, read-only interface
public:
void f() {
x_ = 10; // Note use of private var
}
const int& x;
myClass() : x_(42), x(x_) {} // must have constructor to initialize reference
};
int main() {
myClass temp;
// temp.x is const, so ...
cout << temp.x << endl; // works
// temp.x = 57; // fails
}
EDIT: With a proxy class, you can get precisely the syntax you asked for:
class myClass {
public:
template <class T>
class proxy {
friend class myClass;
private:
T data;
T operator=(const T& arg) { data = arg; return data; }
public:
operator const T&() const { return data; }
};
proxy<int> x;
// proxy<std::vector<double> > y;
public:
void f() {
x = 10; // Note use of private var
}
};
temp.x appears to be a read-write int in the class, but a read-only int in main.
A simple solution, like Rob's, but without constructor:
class myClass {
private:
int m_x = 10; // Note: name modified from read-only reference in public interface
public:
const int& x = m_x;
};
int main() {
myClass temp;
cout << temp.x << endl; //works.
//temp.x = 57; //fails.
}
It is more like get method, but shorter.
Constant pointer is simple, and should work at all types you can make pointer to.
This may do what you want.
If you want a readonly variable but don't want the client to have to change the way they access it, try this templated class:
template<typename MemberOfWhichClass, typename primative>
class ReadOnly {
friend MemberOfWhichClass;
public:
inline operator primative() const { return x; }
template<typename number> inline bool operator==(const number& y) const { return x == y; }
template<typename number> inline number operator+ (const number& y) const { return x + y; }
template<typename number> inline number operator- (const number& y) const { return x - y; }
template<typename number> inline number operator* (const number& y) const { return x * y; }
template<typename number> inline number operator/ (const number& y) const { return x / y; }
template<typename number> inline number operator<<(const number& y) const { return x <<y; }
template<typename number> inline number operator>>(const number& y) const { return x >> y; }
template<typename number> inline number operator^ (const number& y) const { return x ^ y; }
template<typename number> inline number operator| (const number& y) const { return x | y; }
template<typename number> inline number operator& (const number& y) const { return x & y; }
template<typename number> inline number operator&&(const number& y) const { return x &&y; }
template<typename number> inline number operator||(const number& y) const { return x ||y; }
template<typename number> inline number operator~() const { return ~x; }
protected:
template<typename number> inline number operator= (const number& y) { return x = y; }
template<typename number> inline number operator+=(const number& y) { return x += y; }
template<typename number> inline number operator-=(const number& y) { return x -= y; }
template<typename number> inline number operator*=(const number& y) { return x *= y; }
template<typename number> inline number operator/=(const number& y) { return x /= y; }
template<typename number> inline number operator&=(const number& y) { return x &= y; }
template<typename number> inline number operator|=(const number& y) { return x |= y; }
primative x;
};
Example Use:
class Foo {
public:
ReadOnly<Foo, int> x;
};
Now you can access Foo.x, but you can't change Foo.x!
Remember you'll need to add bitwise and unary operators as well! This is just an example to get you started
You may want to mimic C# properties for access (depending what you're going for, intended environment, etc.).
class Foo
{
private:
int bar;
public:
__declspec( property( get = Getter ) ) int Bar;
void Getter() const
{
return bar;
}
}
There is a way to do it with a member variable, but it is probably not the advisable way of doing it.
Have a private member that is writable, and a const reference public member variable that aliases a member of its own class.
class Foo
{
private:
Bar private_bar;
public:
const Bar& readonly_bar; // must appear after private_bar
// in the class definition
Foo() :
readonly_bar( private_bar )
{
}
};
That will give you what you want.
void Foo::someNonConstmethod()
{
private_bar.modifyTo( value );
}
void freeMethod()
{
readonly_bar.getSomeAttribute();
}
What you can do, and what you should do are different matters. I'm not sure the method I just outlined is popular and would pass many code reviews. It also unnecessarily increases sizeof(Foo) (albeit by a small amount) whereas a simple accessor "getter" would not, and can be inlined, so it won't generate more code either.
You would have to leave it private and then make a function to access the value;
private:
int x;
public:
int X()
{
return x;
}
As mentioned in other answers, you can create read only functionality for a class member by making it private and defining a getter function but no setter. But that's a lot of work to do for every class member.
You can also use macros to generate getter functions automatically:
#define get_trick(...) get_
#define readonly(type, name) \
private: type name; \
public: type get_trick()name() {\
return name;\
}
Then you can make the class this way:
class myClass {
readonly(int, x)
}
which expands to
class myClass {
private: int x;
public: int get_x() {
return x;
}
}
You need to make the member private and provide a public getter method.
The only way I know of granting read-only access to private data members in a c++ class is to have a public function. In your case, it will like:
int getx() const { return x; }
or
int x() const { return x; }.
By making a data member private you are by default making it invisible (a.k.a no access) to the scope outside of the class. In essence, the members of the class have read/write access to the private data member (assuming you are not specifying it to be const). friends of the class get access to the private data members.
Refer here and/or any good C++ book on access specifiers.
Write a public getter function.
int getX(){ return x; }
I had a similiar problem. Here is my solution:
enum access_type{readonly, read_and_write};
template<access_type access>
class software_parameter;
template<>
class software_parameter<read_and_write>{
protected:
static unsigned int test_data;
};
template<>
class software_parameter<readonly> : public software_parameter<read_and_write>{
public:
static const unsigned int & test_data;
};
class read_and_write_access_manager : public software_parameter<read_and_write>{
friend class example_class_with_write_permission;
};
class example_class_with_write_permission{
public:
void set_value(unsigned int value);
};
And the .cpp file:
unsigned int software_parameter<read_and_write>::test_data=1;
const unsigned int & software_parameter<readonly>::test_data=software_parameter<read_and_write>::test_data;
void example_class_with_write_permission::set_value(unsigned int value){software_parameter<read_and_write>::test_data=value;};
The idea is, that everyone can read the software parameter, but only the friends of the class read_and_write_access_manager are allowed to change software parameter.
but temp.x = 5; not allowed?
This is any how not allowed in the snippet posted because it is anyhow declared as private and can be accessed in the class scope only.
Here are asking for accessing
cout << temp.x << endl;
but here not for-
int myint = temp.x;
This sounds very contradictory.

c++ about operator* overloading

Is there any possible way to overload operator* in such way that it's assigning and observing functions are defined apart?
class my_class
{
private:
int value;
public:
int& operator*(){return value;}
};
int main()
{
my_class obj;
int val = 56;
*obj = val; // assign
val = *obj; // observe, same operator* is called
}
Sort of -- you can have the operator* return an instance of another class, rather than returning a reference directly. The instance of the other class then defines both a conversion operator and an assignment operator.
(In your sample code, it looks like you've overloaded the multiplication operator when you meant to overload the dereferencing operator; I'll use the dereferencing operator below.)
For example:
class my_class
{
friend class my_class_ref;
public:
my_class_ref operator*() { return my_class_ref(this); }
private:
int value;
};
class my_class_ref
{
public:
operator int() { return owner->value; } // "observe"
my_class_ref& operator=(int new_value) { owner->value = new_value; return *this; } // "assign"
private:
my_class* owner;
my_class_ref(my_class* owner) { this->owner = owner; }
};
There are some caveats. For example, as my_class_ref is implemented with a pointer to its parent class, your code must be careful that my_class_ref always has a lifetime shorter than the lifetime of the corresponding my_class -- otherwise you will dereference an invalid pointer.
In practice, if you pretend that my_class_ref doesn't exist (i.e. never declare a variable with that class) it can work very well.
Write your class like so
class my_class
{
private:
int value;
public:
int operator*() const { // observing
return value;
}
int& operator*() { // assigning
return value;
}
};
Then these operators are dissambiguated by constness, so code like this is possible
int _tmain(int argc, _TCHAR* argv[])
{
my_class a;
*a = 1; // assigning
int k = *(const_cast<my_class const&>(a)); // observing
return 0;
}

Class variables: public access read-only, but private access read/write

Whoopee, not working on that socket library for the moment. I'm trying to educate myself a little more in C++.
With classes, is there a way to make a variable read-only to the public, but read+write when accessed privately? e.g. something like this:
class myClass {
private:
int x; // this could be any type, hypothetically
public:
void f() {
x = 10; // this is OK
}
}
int main() {
myClass temp;
// I want this, but with private: it's not allowed
cout << temp.x << endl;
// this is what I want:
// this to be allowed
temp.f(); // this sets x...
// this to be allowed
int myint = temp.x;
// this NOT to be allowed
temp.x = myint;
}
My question, condensed, is how to allow full access to x from within f() but read-only access from anywhere else, i.e. int newint = temp.x; allowed, but temp.x = 5; not allowed? like a const variable, but writable from f()...
EDIT: I forgot to mention that I plan to be returning a large vector instance, using a getX() function would only make a copy of that and it isn't really optimal. I could return a pointer to it, but that's bad practice iirc.
P.S.: Where would I post if I just want to basically show my knowledge of pointers and ask if it's complete or not? Thanks!
Of course you can:
class MyClass
{
int x_;
public:
int x() const { return x_; }
};
If you don't want to make a copy (for integers, there is no overhead), do the following:
class MyClass
{
std::vector<double> v_;
public:
decltype(v)& v() const { return v_; }
};
or with C++98:
class MyClass
{
std::vector<double> v_;
public:
const std::vector<double>& v() const { return v_; }
};
This does not make any copy. It returns a reference to const.
While I think a getter function that returns const T& is the better solution, you can have almost precisely the syntax you asked for:
class myClass {
private:
int x_; // Note: different name than public, read-only interface
public:
void f() {
x_ = 10; // Note use of private var
}
const int& x;
myClass() : x_(42), x(x_) {} // must have constructor to initialize reference
};
int main() {
myClass temp;
// temp.x is const, so ...
cout << temp.x << endl; // works
// temp.x = 57; // fails
}
EDIT: With a proxy class, you can get precisely the syntax you asked for:
class myClass {
public:
template <class T>
class proxy {
friend class myClass;
private:
T data;
T operator=(const T& arg) { data = arg; return data; }
public:
operator const T&() const { return data; }
};
proxy<int> x;
// proxy<std::vector<double> > y;
public:
void f() {
x = 10; // Note use of private var
}
};
temp.x appears to be a read-write int in the class, but a read-only int in main.
A simple solution, like Rob's, but without constructor:
class myClass {
private:
int m_x = 10; // Note: name modified from read-only reference in public interface
public:
const int& x = m_x;
};
int main() {
myClass temp;
cout << temp.x << endl; //works.
//temp.x = 57; //fails.
}
It is more like get method, but shorter.
Constant pointer is simple, and should work at all types you can make pointer to.
This may do what you want.
If you want a readonly variable but don't want the client to have to change the way they access it, try this templated class:
template<typename MemberOfWhichClass, typename primative>
class ReadOnly {
friend MemberOfWhichClass;
public:
inline operator primative() const { return x; }
template<typename number> inline bool operator==(const number& y) const { return x == y; }
template<typename number> inline number operator+ (const number& y) const { return x + y; }
template<typename number> inline number operator- (const number& y) const { return x - y; }
template<typename number> inline number operator* (const number& y) const { return x * y; }
template<typename number> inline number operator/ (const number& y) const { return x / y; }
template<typename number> inline number operator<<(const number& y) const { return x <<y; }
template<typename number> inline number operator>>(const number& y) const { return x >> y; }
template<typename number> inline number operator^ (const number& y) const { return x ^ y; }
template<typename number> inline number operator| (const number& y) const { return x | y; }
template<typename number> inline number operator& (const number& y) const { return x & y; }
template<typename number> inline number operator&&(const number& y) const { return x &&y; }
template<typename number> inline number operator||(const number& y) const { return x ||y; }
template<typename number> inline number operator~() const { return ~x; }
protected:
template<typename number> inline number operator= (const number& y) { return x = y; }
template<typename number> inline number operator+=(const number& y) { return x += y; }
template<typename number> inline number operator-=(const number& y) { return x -= y; }
template<typename number> inline number operator*=(const number& y) { return x *= y; }
template<typename number> inline number operator/=(const number& y) { return x /= y; }
template<typename number> inline number operator&=(const number& y) { return x &= y; }
template<typename number> inline number operator|=(const number& y) { return x |= y; }
primative x;
};
Example Use:
class Foo {
public:
ReadOnly<Foo, int> x;
};
Now you can access Foo.x, but you can't change Foo.x!
Remember you'll need to add bitwise and unary operators as well! This is just an example to get you started
You may want to mimic C# properties for access (depending what you're going for, intended environment, etc.).
class Foo
{
private:
int bar;
public:
__declspec( property( get = Getter ) ) int Bar;
void Getter() const
{
return bar;
}
}
There is a way to do it with a member variable, but it is probably not the advisable way of doing it.
Have a private member that is writable, and a const reference public member variable that aliases a member of its own class.
class Foo
{
private:
Bar private_bar;
public:
const Bar& readonly_bar; // must appear after private_bar
// in the class definition
Foo() :
readonly_bar( private_bar )
{
}
};
That will give you what you want.
void Foo::someNonConstmethod()
{
private_bar.modifyTo( value );
}
void freeMethod()
{
readonly_bar.getSomeAttribute();
}
What you can do, and what you should do are different matters. I'm not sure the method I just outlined is popular and would pass many code reviews. It also unnecessarily increases sizeof(Foo) (albeit by a small amount) whereas a simple accessor "getter" would not, and can be inlined, so it won't generate more code either.
You would have to leave it private and then make a function to access the value;
private:
int x;
public:
int X()
{
return x;
}
As mentioned in other answers, you can create read only functionality for a class member by making it private and defining a getter function but no setter. But that's a lot of work to do for every class member.
You can also use macros to generate getter functions automatically:
#define get_trick(...) get_
#define readonly(type, name) \
private: type name; \
public: type get_trick()name() {\
return name;\
}
Then you can make the class this way:
class myClass {
readonly(int, x)
}
which expands to
class myClass {
private: int x;
public: int get_x() {
return x;
}
}
You need to make the member private and provide a public getter method.
The only way I know of granting read-only access to private data members in a c++ class is to have a public function. In your case, it will like:
int getx() const { return x; }
or
int x() const { return x; }.
By making a data member private you are by default making it invisible (a.k.a no access) to the scope outside of the class. In essence, the members of the class have read/write access to the private data member (assuming you are not specifying it to be const). friends of the class get access to the private data members.
Refer here and/or any good C++ book on access specifiers.
Write a public getter function.
int getX(){ return x; }
I had a similiar problem. Here is my solution:
enum access_type{readonly, read_and_write};
template<access_type access>
class software_parameter;
template<>
class software_parameter<read_and_write>{
protected:
static unsigned int test_data;
};
template<>
class software_parameter<readonly> : public software_parameter<read_and_write>{
public:
static const unsigned int & test_data;
};
class read_and_write_access_manager : public software_parameter<read_and_write>{
friend class example_class_with_write_permission;
};
class example_class_with_write_permission{
public:
void set_value(unsigned int value);
};
And the .cpp file:
unsigned int software_parameter<read_and_write>::test_data=1;
const unsigned int & software_parameter<readonly>::test_data=software_parameter<read_and_write>::test_data;
void example_class_with_write_permission::set_value(unsigned int value){software_parameter<read_and_write>::test_data=value;};
The idea is, that everyone can read the software parameter, but only the friends of the class read_and_write_access_manager are allowed to change software parameter.
but temp.x = 5; not allowed?
This is any how not allowed in the snippet posted because it is anyhow declared as private and can be accessed in the class scope only.
Here are asking for accessing
cout << temp.x << endl;
but here not for-
int myint = temp.x;
This sounds very contradictory.

How do I create and use a class arrow operator? [duplicate]

This question already has answers here:
What are the basic rules and idioms for operator overloading?
(8 answers)
Closed 4 months ago.
So, after researching everywhere for it, I cannot seem to find how to create a class arrow operator, i.e.,
class Someclass
{
operator-> () /* ? */
{
}
};
I just need to know how to work with it and use it appropriately.
- what are its inputs?
- what does it return?
- how do I properly declare/prototype it?
The operator -> is used to overload member access. A small example:
#include <iostream>
struct A
{
void foo() {std::cout << "Hi" << std::endl;}
};
struct B
{
A a;
A* operator->() {
return &a;
}
};
int main() {
B b;
b->foo();
}
This outputs:
Hi
The arrow operator has no inputs. Technically, it can return whatever you want, but it should return something that either is a pointer or can become a pointer through chained -> operators.
The -> operator automatically dereferences its return value before calling its argument using the built-in pointer dereference, not operator*, so you could have the following class:
class PointerToString
{
string a;
public:
class PtPtS
{
public:
PtPtS(PointerToString &s) : r(s) {}
string* operator->()
{
std::cout << "indirect arrow\n";
return &*r;
}
private:
PointerToString & r;
};
PointerToString(const string &s) : a(s) {}
PtPtS operator->()
{
std::cout << "arrow dereference\n";
return *this;
}
string &operator*()
{
std::cout << "dereference\n";
return a;
}
};
Use it like:
PointerToString ptr(string("hello"));
string::size_type size = ptr->size();
which is converted by the compiler into:
string::size_type size = (*ptr.operator->().operator->()).size();
(with as many .operator->() as necessary to return a real pointer) and should output
arrow dereference
indirect dereference
dereference
Note, however, that you can do the following:
PointerToString::PtPtS ptr2 = ptr.operator->();
run online: https://wandbox.org/permlink/Is5kPamEMUCA9nvE
From Stroupstrup:
The transformation of the object p into the pointer p.operator->() does not depend on the member m pointed to. That is the sense in which operator->() is a unary postfix operator. However, there is no new syntax introduced, so a member name is still required after the ->
class T {
public:
const memberFunction() const;
};
// forward declaration
class DullSmartReference;
class DullSmartPointer {
private:
T *m_ptr;
public:
DullSmartPointer(T *rhs) : m_ptr(rhs) {};
DullSmartReference operator*() const {
return DullSmartReference(*m_ptr);
}
T *operator->() const {
return m_ptr;
}
};
http://en.wikibooks.org/wiki/C++_Programming/Operators/Operator_Overloading#Address_of.2C_Reference.2C_and_Pointer_operators
The "arrow" operator can be overloaded by:
a->b
will be translated to
return_type my_class::operator->()