My program is working fine and does what its supposed to do but the notation used doesn't seems right to me. I have a class with some variables and two functions:
foo.h
class foo{
private:
int a;
public:
void seta1(int value);
void seta2(int value);
};
foo.cpp
void foo::seta2(int value)
{
a = value;
}
void foo::seta1(int value)
{
seta2(value);
}
then when i print variable a it has the value its supposed to have, but wouldn't this notation be more correct?
void foo::seta2(int value)
{
this.a = value;
}
No. this is a pointer, not a reference.
this->a = value would be correct.
The this-> is implied in this case (a a non-static member being accessed in a non-static member function). There are some circumstances where the this-> is required, but this is not one of them.
actually it should be this->a, since this is a pointer. however you don't need to usually write "this" since it's implied. both are correct.
This is only useful if a member variables is over-ridden by a local variable.
For example:
void foo::seta2(int a)
{
this->a = a;
}
Related
As far as I know, the member function pointer only can be assigned to the pointer to member function type, and converted to any other except this will violate the standard, right?
And when calling std::bind(&T::memberFunc, this), it should return a dependent type which depend on T.(in std of VC++ version, it's a class template called _Binder).
So the question becomes to why one std::funcion can cover all _Binder(VC++ version) types.
class A
{
public:
void func(){}
};
class B
{
public:
void func(){}
};
std::function<void(void)> f[2];
A a;
B b;
f[0] = std::bind(&A::func, &a);
f[1] = std::bind(&B::func, &b);
And I can't picture what type of the member of std::funcion which stored the function would be like, unless I am wrong from the first beginning.
This question only covered the member function need to be called with it's instance.
But mine is about why one std::function type can hold all T types.
In short what is happening is that std::bind(&A::func, &a) returns an object of a class similar to
class InternalClass
{
A* a_; // Will be initialized to &a
public:
void operator()(void)
{
a_->func();
}
};
[Note that this is highly simplified]
The callable operator() function is what is matches the void(void) signature of the std::function<void(void)>.
I think the implementation would probably like this:
template</*...*/>
class std::bind</*...*/>
{
public:
std::bind(callable_t call, param_t p)
{
_func = [call, p]()/* using lambda to capture all data for future calling */
{
p->call();
};
}
operator std::function<void(void)>()
{
return _func;
}
private:
std::function<void(void)> _func;
};
And lambda is the key.
I read a line in Meyers:
"A member function that modifies what a pointer points to frequently doesn`t act const.
But if only the pointer is in the object, the function is bitwise const, and compilers wont complain."
I fail to understand that modifying a pointer in a function cannot maintain its bitwise constantness since its a member variable...
Even if we assume that bitwise constantness is only for values that pointers point to and not for the pointer addresses themselves..
Then why does it matter if its the only member variable in the class or if its not the only only member variable..
Basically this means that if you had
struct Foo
{
int bar;
};
you couldn't have a const member function change the value of bar.
However if bar is a pointer to an int, you could change the value of the int in a const method because the int is not actually part of the struct.
Both versions achieve the same goal (i.e. change the value of the int) but in the first version you are breaking bitwise constness and the compiler will complain, in the second it wont.
It's bitwise const because the member function only
modifies what [the] pointer points to
so the object instace data (the member pointer) doesn't change only the object on the heap that it points to.
Take the following simple classes:
class A
{
public:
A(int d = 0) : data(d) {}
void func() const
{
++data; // Can't do this. That's changing
// the bitwise content of this.
}
private:
int data;
};
And
class B
{
public:
A(int d = 0) : data(new int(d)) {}
void func() const
{
++(*data); // Can do this. That doesn't change
// the bitwise content of this.
}
private:
int* data;
};
If I read it correctly, a member function usually isn't qualified const if it modifies a value pointed at by a pointer stored in the current object:
class A {
char* string;
public:
void UpCaseString() { strupr(string); }
....
}
The UpCaseString() method modifies data which 'belong' to the object, so it usually would not be declared as const. However it actually modifies some buffer allocated outside the current object, the instance of A class has only a char* pointer to the buffer—so the buffer can still be modified even when the object itself is const:
class A {
char* string;
public:
void UpCaseString() const { strupr(string); }
....
}
void foo(A const &a) {
a.UpCaseString();
}
Member a.string is not modified here.
My question is about this operator in C++, should we use it as much as possible? I given the following example to show my point:
class Abc
{
public:
int a_;
void fun();
};
void Abc::fun()
{
// option 1
a_ = 3;
// option 2
this->a_ = 3;
}
In the function class member fun(), we can invoke member variables in two ways, one is using this-> and the other is not using it. So my question is: which practice is encouraged? Thanks.
Under ordinary circumstances, you're right that you can use both. In such case, it's just a matter of style and the correct thing to do is follow the style guide of your project. Consistency is more important than personal preference in this regard.
However, there are two situations where using this-> can make a difference. One is when the member function has a parameter with the same name as a member; in such case, the name of the parameter hides the name of the member and you have to use this-> to refer to the member (first pointed out by #Krypton's answer):
void Abc::fun(int a_)
{
a_ = 3; // assigns into the parameter
this->a_ = 3; // assigns into the data member
}
The other situation is when you're working inside a class template and the member is inherited from a base class which depends on template parameters of your class template. In such case, unqualified lookup does not search dependent contexts and so the member would not be found. Using this-> turns the access into a dependent expression, which will be looked up at instantiation time, and thus resolved to the member correctly. Example:
template <class T>
struct Base
{
protected:
T a_;
};
template <class T>
struct Abc : Base<T>
{
void fun() {
a_ = 3; // error, not `a_` in scope
this->a_ = 3; // OK, found at instantiation time
}
};
In this situation, an alternative solution exists: make the name visible explicitly:
template <class T>
struct Abc : Base<T>
{
protected:
using Base<T>::a_;
public:
void fun() {
a_ = 3; // OK, found thanks to `using` declaration
}
};
If the variable and the parameter are named the same, using this is a must.
class Foo
{
public:
int _a;
void func(int _a) {
this->_a = _a;
}
};
this is also required when referring to a member of a base class that depends on a template parameter of the current class.
Otherwise, it is not necessary to use this.
I think it is more a matter of style. The use of additional this-> does not change the produced code.
Though you cannot use operator this-> in the initialization of class members before the constructor body, like
class Abc {
public:
Abc(int i): /*this-> is incorrect*/i(i) {}
private:
int i;
};
I prefer to use this-> to have a clear difference with other no-class members.
Then the code like the following is more readable
void foo(int i) { }
class Abc {
public:
Abc(int j) { this->foo(j); }
private:
void foo (int i) { this->i = i; }
int i;
};
Some people name class data members starting with m_, like m_i, m_j.
Some modern IDEs support semantic syntax highlighting that also helps to distinguish between local variables, class data members, global variables, functions.
I realy don't understand why it works, but below code shows an example of calling private method from the world without any friend classes:
class A
{
public:
virtual void someMethod(){
std::cout << "A::someMethod";
}
};
class B : public A
{
private:
virtual void someMethod(){
std::cout << "B::someMethod";
}
};
int main(){
A* a = new B;
a->someMethod();
}
outputs:
B::someMethod
Doesn't it violates encapsulation rules in C++? For me this is insane. The inheritance is public, but the access modifier in derived class is changed to private, thus the someMethod() in class B is private. So in fact, doing a->someMethod(), we are directly calling a private method from the world.
Consider the following code, a modification of the code in the original question:
class A
{
public:
virtual void X(){
std::cout << "A::someMethod";
}
};
class B : public A
{
private:
virtual void Y(){
std::cout << "B::someMethod";
}
};
int main(){
A* a = new B;
a->X();
}
It's easy to understand that it's legit to call X(). B inherits it from A as a public member. Theoretically if X() would call Y() this would be legit as well of course, although this is not possible because X() is declared in A which doesn't know Y(). But actually this is the case if X = Y, i.e. if both methods have the same name.
You may think of it as "B inherits a public method from A, that calls a private method (of B) with the same name".
a is a pointer to an A object where the method is public, so this is not a violation. Since, you have used virtual, the VTABLE is taken into account and you get the output as B::someMethod.
For me this is quite simple.
As you are allowed to asign any dynamic type inheritance of a class to an object of the parrent-class it would be vise versa.But as you are assigning the Child to its parrent object pointer this could be bad as if the class of B where bigger as A.
If a program attempts to access the stored value of an object through an lvalue of other than one of the following types the behavior is undefined:
the dynamic type of the object,
a cv-qualified version of the dynamic type of the object,
a type that is the signed or unsigned type corresponding to the dynamic type of the object,
a type that is the signed or unsigned type corresponding to a cv-qualified version of the dynamic type of the object,
an aggregate or union type that includes one of the aforementioned types among its members (including, recursively, a member of a subaggregate or contained union),
a type that is a (possibly cv-qualified) base class type of the dynamic type of the object,
a char or unsigned char type.
So as in your code you aren't fitting this conditions, but as B has the sime size as A, it would be possible to run it. But it is undefined behavior.
And as you creat a new B the memory block a is pointing to has the method of printing B and not A.
The access control specifiers (public, protected and private) do not apply to member functions or data members. They apply to member function and data member names. And that works. If you can refer to the member without the name, you can access it.
That's precisely what's happening here. You're calling B::someMethod, but you're calling it using the name A::someMethod, which is public. No problem.
You're suggesting a private member function shouldn't be callable from outside of the class (disregarding friends for the moment). How would your desired semantics work in the following case?
Shared library hider:
hider.h:
typedef void (*FuncType)();
class Hider {
private:
static void privFunc();
public:
static void pubFunc();
FuncType getFunction() const;
};
hider.cpp
#include <cstdlib>
#include <iostream>
#include "hider.h"
void Hider::privFunc() {
std::cout << "Private\n";
}
void Hider::pubFunc() {
std::cout << "Public\n";
}
FuncType Hider::getFunction() const {
if (std::rand() % 2) {
return &pubFunc;
} else {
return &privFunc;
}
}
Application using library hider
#include "hider.hpp"
int main()
{
Hider h;
FuncType f = h.getFunc();
f();
}
What about the call to f()? Should it fail at runtime 50% of the time with some form of access control violation?
As suggested by DyP in the comments, a more realistic scenario is the well-known "template method" design pattern:
class Container
{
public:
void insert(const Item &item) {
preInsert();
data.insert(item);
postInsert();
}
private:
std::vector<Item> data;
virtual void preInsert() = 0;
virtual void postInsert() = 0;
};
class ThreadSafeContainer : public Container
{
private:
std::mutex m;
virtual void preInsert() {
m.lock();
}
virtual void postInsert() {
m.unlock();
}
};
Your semantics would mean this code wouldn't compile.
Can some one please explain the scope of int A and int B in the void func() and in void func1()?
class C {
struct S {
int A;
};
int B
public :
void func(){
}
void func1(){
}
};
Not sure I fully understand what you're asking for, but if I do, I'll try to answer.
Functions func() and func1() are member functions of C, so they have identical access to the exact same names here. Variable B, being a member variable of C, can be referred directly withing func() and func1() without qualifying it with any namespace.
Variable A on the other hand, being a public, non-static member variable of S, requires first instantiating an object of type S before being accessed, like this:
void func()
{
S s;
B = 0; // Directly accessible, member variable of `C`
s.A = B; // A is a non-static member variable of `S`, requires an object
A == 3; // ERROR! A is not a member variable of C
}