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.
Related
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.
I feel like this question must have been asked before but I couldn't find an answer from poking around on google. If it has please direct me to a link and I will remove this post.
Consider this minimal example that represents a larger problem I have. Say I created a simple "Point" and "Printer" class like so:
class Point {
public:
double x, y;
Point() {x = y = 0;}
Point(double x, double y) {
this->x = x; this->y = y;
}
};
template<typename T>
class Printer {
public:
T* mData;
int mSize;
// Constructor
Printer(std::vector<T> &input) {
mData = &input[0];
mSize = input.size();
}
// Simple Print function
void Print() {
printf(" - Showing %d items\n", mSize);
for (int i = 0; i < mSize; i++) {
const T &item = mData[i];
printf(" - Item %d: (%lf, %lf)\n", i, item.x, item.y);
}
}
};
I could use the printer class like this:
std::vector<Point> points; // fill the vector, and then...
Printer<Point> pointsPrinter(points); pointsPrinter.Print();
Now say someone else comes along and wants to use the Printer class with there own "Point" class declared like so:
class Pnt {
public:
double mX, mY;
// other stuff
};
If they try to do this:
vector<Pnt> pnts; // Fill the pnts, and then...
Printer<Pnt> pntsPrinter(pnts);
pntsPrinter.Print(); // COMPILE ERROR HERE!
Obviously this will fail because Pnt has no x or y members. Does there exist a way I can rewrite the Printer class to work with all generic user types? What I DONT want to do is copy a Pnt vector into a Points vector.
EDIT:
The only way I can think to make this work would be to pass in functions pointers. Something like this:
template<typename T>
class Printer {
public:
T* mData;
int mSize;
double* (*mXFunc) (T*);
double* (*mYFunc) (T*);
Printer(std::vector<T> &input,
double* (*xFunc) (T*),
double* (*yFunc) (T*))
{
mData = &input[0];
mSize = input.size();
mXFunc = xFunc;
mYFunc = yFunc;
}
void Print() {
printf(" - Showing %d items\n", mSize);
for (int i = 0; i < mSize; i++) {
T &item = mData[i];
printf(" - Item %d: (%lf, %lf)\n", i, *mXFunc(&item), *mYFunc(&item));
}
}
};
// Could then use it like so
inline double* getXPointVal(Point *point) {return &point->x;}
inline double* getYPointVal(Point *point) {return &point->y;}
inline double* getXPntVal(Pnt *point) {return &point->mX;}
inline double* getYPntVal(Pnt *point) {return &point->mY;}
Printer<Pnt> pntPrinter(pnts, getXPntVal, getYPntVal);
Printer<Point> pointsPrinter(points, getXPointVal, getYPointVal);
pntPrinter.Print();
pointsPrinter.Print();
The problem with this is that it looks ugly and also possibly introduces the function call overhead. But I guess the function call overhead would get compiled away? I was hoping a more elegant solution existed...
If you choose cout instead of printf to write your output, you can allow all printable types to define an overload for the << operator and use that generically inside Printer::print(). An overload could look like this:
std::ostream& operator<<(std::ostream &out, Point& p){
out << "Point(" << p.x << ", " << p.y << ")";
return out;
}
On a side note, I advise against storing a pointer to a vector's internal storage and size member. If the vector needs to reallocate, your pointer will be left dangling and invalid. Instead, you should pass the vector temporarily as a reference or keep a const reference.
You could define free (non-member) functions for each Point class you want to use. The advantage of this is that free functions can be defined later, without making changes to existing classes.
Example:
namespace A {
class Point {
public:
Point (int x, int y) : x_(x), y_(y) {}
int getX () const { return x_; }
int getY () const { return y_; }
private:
int x_, y_;
};
// in addition, we provide free functions
int getX (Point const & p) { return p.getX(); }
int getY (Point const & p) { return p.getY(); }
}
namespace B {
class Pnt {
public:
Pnt (int x, int y) : x_(x), y_(y) {}
int get_x () const { return x_; }
int get_y () const { return y_; }
private:
int x_, y_;
};
// Pnt does not have free functions, and suppose we
// do not want to add anything in namespace B
}
namespace PointHelpers {
// free functions for Pnt
int getX (Pnt const & p) { return p.get_x (); }
int getY (Pnt const & p) { return p.get_y (); }
}
// now we can write
template <class PointTy>
void printPoint (PointTy const & p) {
using PointHelpers::getX;
using PointHelpers::getY;
std::cout << getX (p) << "/" << getY (p) << std::endl;
}
A::Point p1 (2,3);
B::Pnt p2 (4,5);
printPoint (p1);
printPoint (p2);
If the free functions live in the same namespace as the corresponding class, they will be found by argument-dependent name lookup. If you do not want to add anything in that namespace, create a helper namespace and add the free functions there. Then bring them into scope by using declarations.
This approach is similar to what the STL does for begin and end, for instance.
Don't expect from the templates to know which members of given class/structure corresponds to your x and y...
If you want to create generic solution you could tell your printer function how to interpret given object as your Point class using e.g. lambda expression (c++11 solution):
#include <iostream>
class Point {
public:
double x, y;
Point() {x = y = 0;}
Point(double x, double y) {
this->x = x; this->y = y;
}
};
class Pnt {
public:
double mX, mY;
// other stuff
};
template <class P, class L>
void Print(const P &p, L l) {
Print(l(p));
}
void Print(const Point &p) {
std::cout << p.x << ", " << p.y << std::endl;
}
int main() {
Print(Point(1, 2));
Print(Pnt{4, 5}, [](const Pnt &p) -> Point {return Point(p.mX, p.mY);});
}
in C++ is it a bad practice to use reference in place of getters?
for example:
class X
{
int mP;
public:
const int& P;
X():P(mP){}
};
and later
X xl;
int h = xl.P;
Just think about refactoring to make the access thread safe, that won't work well this way and require a lot of changes in the client classes/functions.
If you have class members, that are guaranteed not to be changed over lifetime of the instance, you can simply provide const int P; and initialize it properly in your class' constructors.
If the value is to be visible class wide use a static const int P;
In any other case use a public getter:
int P() const; // a return type of 'const int &' would be redundant
1st shot implementation:
int X::P() const
{
return mP;
}
Thread safe implementation:
class X {
{
// ...
private:
// ...
mutable std::mutex internalDataGuard;
};
int X::P() const
{
std::lock(internalDataGuard);
return mP;
}
None of this is good:
class X { public: int x; };
class X {
private: int m_x;
public: const int& get() const { return m_x; }
public: void set(const int& other) { m_x = other; }
};
class X {
private: int m_x;
public: const int& x() const { return m_x; }
public: void x(const int& other) { m_x = other; }
};
class X {
private: int m_x;
public: const int& x() const { return m_x; }
public: int& x() { return m_x; }
};
Pick one, it's a design decision.
Having 'const int& x' to publish the private member will work:
class X {
private: int m_x;
public: const int& x;
public: X() : m_x(0), x(m_x) {}
// Take care for copy and assignment
};
The cost is a larger memory footprint.
I'm coming to C++ from C# and const-correctness is still new to me. In C# I could declare a property like this:
class Type
{
public readonly int x;
public Type(int y)
{
x = y;
}
}
This would ensure that x was only set during initialization. I would like to do something similar in C++. The best I can come up with though is:
class Type
{
private:
int _x;
public:
Type(int y) { _x = y; }
int get_x() { return _x; }
};
Is there a better way to do this? Even better: Can I do this with a struct? The type I have in mind is really just a collection of data, with no logic, so a struct would be better if I could guarantee that its values are set only during initialization.
There is a const modifier:
class Type
{
private:
const int _x;
int j;
public:
Type(int y):_x(y) { j = 5; }
int get_x() { return _x; }
// disable changing the object through assignment
Type& operator=(const Type&) = delete;
};
Note that you need to initialize constant in the constructor initialization list. Other variables you can also initialize in the constructor body.
About your second question, yes, you can do something like this:
struct Type
{
const int x;
const int y;
Type(int vx, int vy): x(vx), y(vy){}
// disable changing the object through assignment
Type& operator=(const Type&) = delete;
};
Rather than a collection of constants, you could have a constant collection. The property of being constant seems to pertain to your use case, not the data model itself. Like so:
struct extent { int width; int height; };
const extent e { 20, 30 };
It's possible to have specifically constant data members of a class, but then you need to write a constructor to initialize it:
struct Foo
{
const int x;
int & y;
int z;
Foo(int a, int & b) : x(a + b), y(b), z(b - a) { }
};
(The example also shows another type of data member that needs to be initialized: references.)
Of course, structs and classes are the same thing.
You can initialize class const members with constructor. If you need add some other logic in constructor, but in .cpp file not in .h, you can create a private method and call it in constructor.
File.h
class Example
{
private:
const int constantMember1;
const int constantMember2;
const int constantMember3;
void Init();
public:
Example(int a, int b) :constantMember1(a), constantMember2(b), constantMember3(a + b) {
//Initialization
Init();
};
};
File.cpp
void Init()
{
//Some Logic intialization
}
This is not exactly answering the question asked, but if you wanted to have the simplicity of directly accessing member variables in a struct without getters, but wanted to ensure that nobody could modify the values, you could do something like this:
#include <iostream>
using namespace std;
class TypeFriend;
struct Type
{
const int &x;
const int y;
Type (int vx, int vy):x (_x), y (vy), _x (vx)
{
}
private:
friend class TypeFriend;
int _x;
};
struct TypeFriend
{
TypeFriend (Type & t):_t (t)
{
}
void setX (int newX)
{
_t._x = newX;
}
private:
Type & _t;
};
int main ()
{
Type t (1, 2);
TypeFriend tf (t);
cout << t.x << "," << t.y << endl;
// t.x = 6; // error: assignment of read-only location ‘t.Type::x’
// cout<<t.x << ","<<t.y<<endl;
tf.setX (5);
cout << t.x << "," << t.y << endl;
return 0;
}
The result of running this is:
1,2
5,2
Type::x cannot be modified externally, so it is read-only, but via TypeFriend it can be changed. This can be useful if you wanted to expose a simple interface of direct member access for reading, but wanted to restrict how those members could be changed.
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.