The following code does not compile, saying " error C2248: 'A::getMe' : cannot access private member declared in class 'A'". Why? I am trying to call the public interface.
class B
{
};
class A
{
public:
const B& getMe() const;
private:
B& getMe();
};
int main()
{
A a;
const B& b = a.getMe();
return 0;
}
Part of the problem which wasn't mentioned in other answers is that accessibility and visibility are independent concepts in C++. The B& A::getMe() private member is visible in main even if it isn't accessible. So in your call a.getMe() there are two overloaded members to consider, B& A::getMe() and B const& A::getMe() const. As a is not const it is the private member which is selected. Then you get an error because it isn't accessible. If you hadn't the private non const member function, you would have the const member as the only possibility and it would have be called as a const member can be called on non const object.
Note that if visibility was conditioned to accessibility, you could have other kind of confusing behavior: you refactor a member, putting a call to a private member outside the class. Now, the private member is no more accessible and so the call is to a different member which is public. That silent change of behavior can lead to bugs hard to track.
In conclusion: whatever are the rule of your language, never overload with different accessibility, it leads to confusion.
In C++, you cannot overload on the return type. Overloading member functions based on their constness is no exception: You overload on the constness of the object the function is called on, not the return type.
To do what you want is a once-in-a-lifetime opportunity to use const_cast to add constness:
const B& b = const_cast<const A&>(a).getMe();
Of course, while this is strange and funny, it might be easier to read if you do it this way:
const A& const_a = a;
const B& b = const_a.getMe();
a is not const in a.getMe(), so the compiler does not realise you are trying to use the const overload of the method.
A const a;
const B& b = a.getMe();
will work as you expect (except that A needs initialising).
It is because to call the const method over the non const method, a should be const to prevent the compiler selecting the non const method.
Would it not be easier to call the private memeber function something else to avoid confusion of having two functions with the same names but differing access.
Related
Let's say we have a class with a single private variable and a max method that takes a single parameter of the same type of the class:
class A
{
private:
int Number;
public:
A() : Number(0) {}
A(int val) : Number(val) {}
int max(A b)
{
if( Number > b.Number )
return Number;
return b.Number;
}
};
What is strange to me is that the parameter b in the max method has access to the private variable Number. However in the main function we do not have access to the parameter Number (as expected since it is declared private)
int main()
{
A a;
a.Number = 0; // ERROR
return 0;
}
So my question is why does the function in the class have access to the variable Number when it is declared private.
It's just the rule, that's all.
It's designed to make member functions, especially functions like assignment operators, copy constructors, and overloaded operators, simpler to write. If you couldn't access the members of the "other" object directly then you'd need a plethora of friend declarations or ugly "getters"; the latter tend to offer little more than a circumvention of encapsulation.
Perhaps the way you propose could have been the default, and to bring in the private and protected members and functions could have required the declaration
friend class;
But C++ was not designed this way, and that proposal would now be an hideous breaking change. Something to muse on though to recover your expected behaviour could be a declaration
friend class = delete;
which would, as far as I can tell, not be a breaking change. Why not propose something of this form to the ISO C++ Committee?
The principle idea behind encapsulation is to hide the internals of a class from external classes.
When you consider that the function you're writing is internal to the class A, it makes sense for the function to be aware of A's internals - regardless of the context.
Consider the following situation
class A
{
public:
void someFunc() const
{
b->nonConstFunction(); //this is a non const function in the class B
}
private:
B* b;
};
In the constant function someFunc() I can call any nonconstant method of b and it will compile. So the function someFunc() is somehow not a true const function. But all best practices says that one should put const anywhere you can. Should this advice be applied also here?
May be declaring the function void someFunc() nonconstant is more honest then void someFunc() const. Or may be there is a more general advice to handle this kind of things?
is somehow not a true const function
well, it depends what you want to express.
if A's state logically depends on b's state (this is the implication I get from your question)
simplest solution is to give A a member of type B, instead of using either a pointer or a reference. Then you have a const B in your const method, and this expresses your requirement directly
next simplest is to just declare the member as const B *b; in the first place - obviously this doesn't work if you also need non-const methods of A to call non-const methods on b.
if you need the indirection, another possibility is to use a smart pointer class (I'm not sure if a suitable one already exists) with operator overloads like
B* operator->();
const B* operator->() const;
which would give the guarantee you want
if A's state does not logically depend on b's.
In this case you don't have a problem: mutating b in a const method is fine, since A's logical state doesn't change. This might often be the case where you have a pointer to eg. a logger, which would otherwise need lots of mutable members.
It's const if A does not "own" B. Modern C++ expresses that by making b a unique_ptr is A is the owner and a plain pointer if just a link.
It would seem that C++ views B as not being part of A but that A is connected to B. As B is not const then A can call its non-const methods. But because A is const you can't make A point to a different B. If you make B a member then you can no longer call its non-const methods because its now part of A.
I thought using a std::unique_ptr would fix this but apparently std::unique_ptr returns a non-const pointer from its const arrow operator ->.
You could fix this by creating a pointer wrapper that passes the constness on to the contained pointer, something like this:
template<typename T>
class const_correct_ptr
{
public:
const_correct_ptr(std::unique_ptr<T>): p(std::move(p)) {}
// pass constness onto target
T* operator->() { return p.get(); }
T const* operator->() const { return p.get(); }
private:
std::unique_ptr<T> p;
};
class B
{
public:
void nonConstFunction() {}
};
class A
{
public:
A(): b(std::make_unique<B>()) {}
void someFunc() const
{
b->nonConstFunction(); // compile time error!
}
private:
const_correct_ptr<B> b;
};
I have a unusual situation,
Say I have a class like the following,
template <typename T>
class C
{
public :
C (int size) : value_(size), some_other_member_(size) {}
T &value () {return value_;}
const T &value() const {return value_;}
private :
T value_;
SomeOtherType some_other_member_;
};
The class designed such that the client can have full access to the member value_, just like std::vector's operator[] will return a reference, this class also have to give client the full access through returning a reference. A setter/getter pair will not do.
However, unlike std::vector, I don't want to allow the client to be able to replace the member entirely. That is, the client shall be able to call const or non-const members of value_, but the following shall not be allowed,
C<SomeType> c(10);
SomeType another_value(5);
c.value() = another_value; // This shall not be allowed
Is there any possible way that I can give client the full access to value_. In some sense, the class C shall be like a container, but once the thing it contained is initialized (through the constructor, there are requirements to T, but that is not relevant here), client can only modify value_ through T's member functions, not replace value_ by assignment.
However, requires T be un-copyable is not an option to me. Because the class C can be copied. At the core of the problem, is that as seen in the class C, C has a few members, they all have a size property, when constructed, they are all constructed with the same size, if value_ is allowed to be replaced through assignment, then it allows the data structure being corrupt in the sense that members may no longer have the same size property.
Requiring T to only allow copy or assignment when the size is the same is also not an option. Because, when copy a C object, the size can be different between the source and the destination. For example,
C c1(10);
C c2(20);
c1 = c2;
is perfectly reasonable. The size of c1 is changed, but all of its members are also changed to the same new size, so it is OK.
I hope I have stated the problem clear. I summary, I want C does not pose much restriction on T, T can be basically any type with a required constructor. T can be copied and assigned. The only thin I don't want client to do is assignment to value_ through C::value().
If you want the user to be able to call non-const member functions on the object and you want to return a reference to the actualy object, you can't completely prohibit assignment, since the assignment operator is basically just that (you can rewrite a = b as a.operator=(b)). Therefore you either need to return only a const reference to your object, make the contained object non_copyable or live with the fact, that it can be assigned to.
Personally I would suggesting rethinking the design. Even if you could disallow assignment, there are really no guarantees that the object doesn't have a member function, which does basically the same think (.swap(...) is a typical candidate), so you haven't really won anything as long as you allow calling non const memberfunctions.
However if you are only concerned with disallowing accidential assignments, you can make it harder to make such an assignment. If your T isn't a builtin, you could create a derived class, which doesn't expose a public assignment operator and return a reference to that:
template <typename T>
class C{
public :
class Derived: public T {
private:
Derived(int size):T(size) {}
Derived& operator=(const Derived&) = default; //used C++11 syntax for brevity, for C++03 code it has to be implemented here
Derived(const Derived&) = default; //don't want this class to be copyied outside of C
~Derived() = default;
friend class C;
};
C (int size) : value_(size), some_other_member_(size) {}
Derived& value () {return value_;}
const Derived& value() const {return value_;}
private :
Derived value_;
SomeOtherType some_other_member_;
};
This will give access to all public members by inheritence, but hide assignment operator (and constructors). Of course if you use c++11, this code could be enhanced by using/defining move constructors/assignments and using perfect forwarding, to allow different constructors. Note that the T-part of Derived can still be assigned to using static_cast<T&>(C.value()) = foo;
To support types you can't derive from (builtins...), you'd need to create a proxy, which exposes all functionality except assignments.
As to your getter/setter problem, I would write
const T& value() const; // as getter
void value(const T&); // as setter
Returning const T& (const-reference) is exactly against situations like c.value() = 10 (see eg. Effective C++ by Scott Meyers, item 23).
I think this also solves the copy problem: your class remains copyable.
I have a class with a member which is not changed by the methods of the class, so I marked it as const. My problem is that I was using the default assignment operator just like a copy constructor in order to avoid multiple declarations. But in this case the assignment operator is not automatically generated, so I get some compiler errors:
'operator =' function is unavailable. This seems like that there is no real life scenario where const class members can be actually used (e.g. have you seen any const member in the STL code?).
Is there any way to fix this, beside removing the const?
EDIT: some code
class A
{
public :
const int size;
A(const char* str) : size(strlen(str)) {}
A() : size(0) {}
};
A create(const char* param)
{
return A(param);
}
void myMethod()
{
A a;
a = create("abcdef");
// do something
a = create("xyz");
// do something
}
Here's your misconception which is causing this issue:
[..] which is not changed by the methods of the class
The member variable is changed by a method of your class, the assignment operator. Including the one synthesized by the compiler. If you mark a member variable as const, this expresses that this variable will (should not!) change its value during the lifetime of the object. So clearly, assigning a new value to the object violates this statement. So if you indeed don't want the member to change, just don't make it const.
const members are ideal in many, many cases. of course, there is the obvious case where a value should not or must not change, but it's also an important restriction for optimization and concurrency -- not every type needs or should have an assignment operator.
if the member needs the behavior of assignment, then the variable must not be const.
when the value/member must not mutate or be mutated by this, it's clearer to provide a separate interface for the variable members (or even a subtype->composition in more complex cases):
class t_text {
public:
// ...
public:
void setString(const std::string& p);
private:
const t_text_attributes d_attributes;
std::string d_string;
};
therefore, my suggestion is to hide the assignment operator, and to make the 'mutable chunk' or member set-able for clarity:
text.setString("TEXT"); // << Good: What you read is what happens.
text = otherText; // << Bad: Surprise - attributes don't actually change!
You cannot have a const member and support assignment, at least not
assignment with the expected semantics. const is, logically, a
promiss that the member will never change, and assignment is
(implicitly, in the minds of most people) a promiss that all data
members will take the values of the members of the right hand side
(which normally means changing). There's a very definite conflict
between these two promisses.
Of course, a lot of types shouldn't support assignment to begin with;
for types that don't support assignment, there's no problem declaring a
data member const. On the whole, however, I've found const a lot
less useful here; const is part of a contract, and data members are
not usually part of the external contract of the class. (But a lot
depends—if the data member is public or protected, then the fact
that it is immutable could be part of the external contract. And of
course, there's nothing wrong with expressing internal class invariants
in language constructs, either.)
Yes, you can override the assignment operator.
Because you're using the default one, the compiler will try to copy the const members also. Which is illegal, since it's const.
class A
{
private:
const int a;
public :
A() : a(0) {}
A& operator = (const A& other) {return *this;}
};
int main()
{
A a;
A b;
a = b; //this is legal if operator = is declared
}
We make a non-member function a friend of a class when we want it to access that class's private members. This gives it the same access rights as a static member function would have. Both alternatives would give you a function that is not associated with any instance of that class.
When must we use a friend function? When must we use a static function? If both are viable options to solve a problem, how do we weigh up their suitability? Is there one that should be preferred by default?
For example, when implementing a factory that creates instances of class foo which only has a private constructor, should that factory function be a static member of foo (you would call foo::create()) or should it be a friend function (you would call create_foo())?
Section 11.5 "The C++ Programming Language" by Bjarne Stroustrup states that ordinary member functions get 3 things:
access to internals of class
are in the scope of the class
must be invoked on an instance
friends get only 1.
static functions get 1 and 2.
The question seems to address the situation where the programmer needs to introduce a function that does not work on any instance of a class (hence the possibility of choosing a static member function). Therefore, I will limit this answer to the following design situation, where the choice is between a static function f() and a friend free function f():
struct A
{
static void f(); // Better this...
private:
friend void f(); // ...or this?
static int x;
};
int A::x = 0;
void A::f() // Defines static function
{
cout << x;
}
void f() // Defines friend free function
{
cout << A::x;
}
int main()
{
A::f(); // Invokes static function
f(); // Invokes friend free function
}
Without knowing anything in advance about the semantics of f() and A (I'll come back to this later), this limited scenario has an easy answer: the static function is preferable. I see two reasons for this.
GENERIC ALGORITHMS:
The main reason is that a template such as the following can be written:
template<typename T> void g() { T::f(); }
If we had two or more classes that have a static function f() on their interface, this would allow us writing one single function that invokes f() generically on any such class.
There is no way to write an equivalent generic function if we make f() a free, non-member function. Although it is true that we could put f() into a namespace, so that the N::f() syntax could be used to mimic the A::f() syntax, it would still be impossible to write a template function such as g<>() above, because namespace names are not valid template arguments.
REDUNDANT DECLARATIONS:
The second reason is that if we were to put the free function f() in a namespace, we would not be allowed to inline its definition directly in the class definition without introducing any other declaration for f():
struct A
{
static void f() { cout << x; } // OK
private:
friend void N::f() { cout << x; } // ERROR
static int x;
};
In order to fix the above, we would to preceed the definition of class A with the following declaration:
namespace N
{
void f(); // Declaration of f() inside namespace N
}
struct A
{
...
private:
friend void N::f() { cout << x; } // OK
...
};
This, however, defeats our intention of having f() declared and defined in just one place.
Moreover, if we wanted to declare and define f() separately while keeping f() in a namespace, we would still have to introduce a declaration for f() before the class definition for A: failing to do so would cause the compiler to complain about the fact that f() had to be declared inside namespace N before the name N::f could be used legally.
Thus, we would now have f() mentioned in three separate places rather than just two (declaration and definition):
The declaration inside namespace N before A's definition;
The friend declaration inside A's definition;
The definition of f() inside namespace N.
The reason why the declaration and definition of f() inside N cannot be joined (in general) is that f() is supposed to access the internals of A and, therefore, A's definition must be seen when f() is defined. Yet, as previously said, f()'s declaration inside N must be seen before the corresponding friend declaration inside of A is made. This effectively forces us to split the declaration and the definition of f().
SEMANTIC CONSIDERATIONS:
While the above two points are universally valid, there are reasons why one might prefer declaring f() as static over making it a friend of A or vice versa which are driven by the universe of discourse.
To clarify, it is important to stress the fact that a member function of a class, whether it is static or non-static, is logically part of that class. It contributes to its definition and thus provides a conceptual characterization of it.
On the other hand, a friend function, in spite of being granted access to the internal members of the class it is friend of, is still an algorithm which is logically external to the definition of the class.
A function can be friend of more than one class, but it can be member of just one.
Thus, in a particular application domain, the designer may want to keep into consideration the semantics of both the function and the class when deciding whether to make the former a friend or a member of the latter (this applies not only to static functions, but to non-static functions as well, where other language constraints may intervene).
Does the function logically contribute to characterize a class and/or its behavior, or is it rather an external algorithm? This question can't be answered without knowledge of the particular application domain.
TASTE:
I believe that any argument other the ones just given stems purely from a matter of taste: both the free friend and the static member approach, in fact, allow to clearly state what the interface of a class is into one single spot (the class's definition), so design-wise they are equivalent (modulo the above observations, of course).
The remaining differences are stylistic: whether we want to write the static keyword or the friend keyword when declaring a function, and whether we want to write the A:: class scope qualifier when defining the class rather than the N:: namespace scope qualifier. Thus, I will not comment further on this.
The difference is clearly expressing the intent of the relationship between the class and the function.
You use friend when you want to intentionally indicate a strong coupling and special relationship between two unrelated classes or between a class and a function.
You use static member function when the function is logically a part of the class to which it is a member.
Friend functions (and classes) can access the private and protected members of your class.
There's rarely a good case for using a friend function or class. Avoid them in general.
Static functions may only access static data (that is, class-scoped data). They may be called without creating an instance of your class. Static functions are great for circumstances you want all of the instances of your class to behave the same way. You can use them:
as callback functions
to manipulate class-scoped members
to retrieve constant data that you don't want to enumerate in your header file
Static functions are used when you want a function that is the same for every instance of a class. Such functions do not have access to "this" pointer and thus cannot access any non static fields. They are used often when you want a function that can be used without instantiating the class.
Friend functions are functions which are not in the class and you want to give them access to private members of your class.
And this(static vs. friend) is not a matter of using one vs the other since they are not opposites.
The standard requires that operator = () [] and -> must be members, and class-specific
operators new, new[], delete and delete[] must be static members. If the situation
arises where we don't need the object of the class to invoke a function, then make
the function static. For all other functions:
if a function requires the operators = () [] and -> for stream I/O,
or if it needs type conversions on its leftmost argument,
or if it can be implemented using the class' public interface alone,
make it nonmember ( and friend if needed in the first two cases)
if it needs to behave virtually,
add a virtual member function to provide the virtual behaviour
and implement in terms of that
else
make it a member.
Static function can only access members of one class. Friend function has access to several classes, as explained by the following code:
class B;
class A { int a; friend void f(A &a, B &b); };
class B { int b; friend void f(A &a, B &b); };
void f(A &a, B &b) { std::cout << a.a << b.b; }
f() can access data of both A and B class.
One reason to prefer a friend over static member is when the function needs to be written in assembly (or some other language).
For instance, we can always have an extern "C" friend function declared in our .cpp file
class Thread;
extern "C" int ContextSwitch(Thread & a, Thread & b);
class Thread
{
public:
friend int ContextSwitch(Thread & a, Thread & b);
static int StContextSwitch(Thread & a, Thread & b);
};
And later defined in assembly:
.global ContextSwitch
ContextSwitch: // ...
retq
Technically speaking, we could use a static member function to do this, but defining it in assembly won't be easy due to name mangling (http://en.wikipedia.org/wiki/Name_mangling)
Another situation is when you need to overload operators. Overloading operators can be done only through friends or non-static members. If the first argument of the operator is not an instance of the same class, then non-static member would also not work; friend would be the only option:
class Matrix
{
friend Matrix operator * (double scaleFactor, Matrix & m);
// We can't use static member or non-static member to do this
};
A static function is a function that does not have access to this.
A friend function is a function that can access private members of the class.
You would use a static function if the function has no need to read or modify the state of a specific instance of the class (meaning you don't need to modify the object in memory), or if you need to use a function pointer to a member function of a class. In this second instance, if you need to modify the state of the resident object, you would need to pass this in and use the local copy. In the first instance, such a situation may happen where the logic to perform a certain task is not reliant on an object's state, yet your logical grouping and encapsulation would have it be a member of a specific class.
You use a friend function or class when you have created code that is not a member of your class and should not be a member of your class, yet has a legitimate purpose for circumventing the private/protected encapsulation mechanisms. One purpose of this may be that you have two classes that have need of some common data yet to code the logic twice would be bad. Really, I have only used this functionality in maybe 1% of the classes I've ever coded. It is rarely needed.
A friend function can not be inherited while a static function can be. So when an aim can be achieved with both static function and friend function, think that whether you want to inherit it or not.
Static function can be used in many different ways.
For example as simple factory function:
class Abstract {
private:
// no explicit construction allowed
Abstract();
~Abstract();
public:
static Abstract* Construct() { return new Abstract; }
static void Destroy(Abstract* a) { delete a; }
};
...
A* a_instance = A::Conctruct();
...
A::Destroy(a_instance);
This is very simplified example but I hope it explains what I meant.
Or as thread function working with Your class:
class A {
public:
static void worker(void* p) {
A* a = dynamic_cast<A*>(p);
do something wit a;
}
}
A a_instance;
pthread_start(&thread_id, &A::worker, &a_instance);
....
Friend is completely different story and they usage is exactly as described by thebretness
Friend functions can access the private and protected members of other classes.
Means they can be used to access all the data weather it is private or public.
So friend functions are used to access that data which static methods can not.
Those methods are made static which are called so many times that declaring a different location inside every object, for them becomes too costly(In terms of memory).
This can be made clear with the help of example:
Let the class's name is fact and its data member is n(which represents integer whose factorial is concern)
then in this case declaring find_factorial() as static would be wise decision!!
They are used as callback functions
to manipulate class-scoped members
to retrieve constant data that you don't want to enumerate in your header file
Now we are clear with following questions..
When a friend function is used? When a static function is used?
Now If both are viable options to solve a problem,
We can weight up their suitability in terms of accessibility(accessibility of Private data) and memory efficiency.
By default no one can be preferred as there are many situation when we need better memory management and sometimes we are are concerned with the scope of data.
For example:
foo::create() will be preferred over create_foo() when we have to call create() method after every small instance of time and we are not interested on scope of data(Private data)
And if we are interested to get the private information of more than one class(s) then create_foo() will be preferred over foo::create().
I hope this would help you!!
Here is what I think it is:
Friend function- when you need access to a different class member, but the classes are not related. Static function- when you no not need access to the 'this' pointer. But, I have a feeling there is more to it....
Static data members always share the memory.
only static function can used static data members.
static member function can be called with class name.
They must be defined outside of the class when we create a object of static member or member function in the class. It will automatically initialize the value.
It always used keyword static.
Static members can share by all the objects.
Type and scope of data members and member function is outside of the class.
A static member variable must be defined outside of the class.