Now I have here a code snippet that I am trying to understand. I thought that only friend functions could access private member variables, so why is the method 'grad' able to access 'a' here to get its size?
#include <vector>
using namespace std;
class Polynom{
private:
vector<double> a;
public:
Polynom(const vector<double>& v): a(v) {}
int grad() { return a.size()-1; }
};
int main()
{
return 0;
}
Ask yourself, if private member access disqualified the rest of the class from access, what would be the point of a private field? You declare a potentially complex object, and then literally can do nothing with it? You have a private region that can interact with itself, but which cannot have any effect on any public facing functionality? You use the private structures as middlemen to write to public fields that you then use? None of these scenarios makes that much sense. Access modifiers protect the class from external influences, but the OOP model assumes the programmer will take care of themselves within the class.
It is noteworthy that there is one condition in which private members can not be accessed: Inheritance. The base class private variables are there in a derived class, but cannot be referenced directly. To be clear,these are the base class' private variables. The child class has its own private scope that it can declare within and access normally.
Related
Note that class x and y are two separate entities and you can not see their private data members from outside of their bodies.
It is known that from int main() I can not see the private member of class x or y.
My question in the following code in line 22:
Why class x can see the private members of class y ? (note here I am sending class y as reference not as a copy) isn't the referenced class y should be protected from strangers like class x ?
Note that the function getForeignNumber(const Player &r) inside class x is not a friend to class y!
#include<iostream>
class Account{
private:
int number{ } ;
public:
Account(int numberValue)
:number{numberValue}
{
std::cout<<"constructor is called"<<std::endl;
}
int getLocalNumber()
{
return this->number;
}
int getForeignNumber(const Account &r)
{
return r.number; // line 22
}
};
int main()
{
Account x{1};
Account y{2};
std::cout<<"get local number="<<x.getLocalNumber()<<std::endl;
std::cout<<"get foreign number x ="<<x.getForeignNumber(x)<<std::endl;
std::cout<<"get foreign number y="<<y.getForeignNumber(y)<<std::endl;
std::cout<<"Hello world"<<std::endl;
return 0;
}
First of all, you are confusing instances of a class with the class. x and y are two instances of the same class Account.
Your analogy isnt sound. Two instances of the same class aren't "strangers". They can access all the internals of each other. Thats how access works.
From cppreference:
All members of a class (bodies of member functions, initializers of member objects, and the entire nested class definitions) have access to all names the class can access. A local class within a member function has access to all names the member function can access.
In other words, access is per class not per instance. If x would not be able to access ys private members it would be impossible for example to write a copy constructor (without getter methods, which would be silly).
PS: By the way, "see" is the wrong word. There are certain circumstances where you can "see" that there is a private member from outside of the class, you just cannot access it. One such situation is when the name of a private method shadows that of a publicly inherited method https://godbolt.org/z/Kzf5KWv4W. Hence, even colloquially "see" is the wrong word for access.
The function getForeignNumber() can see private members of class Account because getForeignNumber() is a member of class Account.
private members are hidden from entities that are outside the class, not from other instances (objects) of the same class.
Given a class method in C++ that has to be private there, how to make C++/CLI access it. Example: C++ class has a private constructor that shouldn't be exposed to the external user, C++/CLI managed code has to have similar private constructor, but internally it must access private C++ constructor to instantiate a member pointer referring to C++ native class.
Keep in mind, first of all, the goal of making things inaccessible (i.e. private) generally contradicts the goal of making things accessible. If you're able to change the class declaration, then you have some options. I don't know the specifics of your C++/CLI requirements, but perhaps one of these options will give you what you need.
Protected and Inheritance
To an "outsider", private and protected members are equally inaccessible. But to a subclass, private is still private while protected members are accessible. You can gain access to protected members by subclassing. This can be one way to unit test "private" members of a class without fully exposing it to the world.
class A {
protected: // was private
int sum(int a, int b);
};
class TestA : public A {
public:
bool testSum(int expected, int a, int b) {
return expected == sum(a, b);
}
};
So access to protected method sum in class A becomes accessible by making it protected and subclassing. The private member will remain inaccessible to everything else except subclasses.
Static Factory Method
You mentioned a private constructor; if you are needing to manage construction, you might accomplish that with a static factory method. For instance:
class Foobar {
private:
Foobar() { } // Don't let anyone just make one.
public:
static Foobar* Create() { return new Foobar; }
};
// To create a Foobar instance:
Foobar* pfoo = Foobar::Create();
This is not the best interface (better to use a shared_ptr, for instance), but it demonstrates my meaning. Note that since the factory function Create is public, anyone can create one. However, you can change the body of Create to something more complex: include bookkeeping, initialization, etc. The factory method is a way to manage creation, not restrict it. Granted, you may not want this, but it's an option if you need to manage construction.
Friends
C++ permits giving access of the private parts of classes to other classes/functions via the friend keyword.
class A {
int x; //private
friend class B;
};
class B {
void foobar(A& a) {
a.x = 42; // permissible, because A declared class B a friend
}
};
Friendship can be granted to another class or to a function. This can easily break encapsulation and make code difficult to follow or keep safe, but it also gives you the means to expose private members to exactly just those who need it.
I saw something like the following in a IKM test, the code is in a single file:
class A{
public:
int a;
A();
protected:
int x;
private:
int y;
};
void ARandomFunction(){
//Implementation
}
which variables of class A can ARandomFunction() access? Generally speaking what can be accessed if the decalarations are all in the same file?
Those variables will be per-instance (non-static member variables), so you first need to create an object to access them. Only public members can be accessed from a free-standing function unless the function is declared friend of that class in which case all members can be accessed.
That said it doesn't matter if they are in the same file or not. Once the class definition is visible where the function is implemented the members can be accessed.
Being in the same file changes nothing, your function can only access a as it is public and your function is not a member of A (for the private members) nor a sub class of it (for the protected members).
To my knowledge, using your above example ARandomFUnction can access the public variables and functions regardless of inheritance. THe protected variables can only be accessed if ARandomFunction is contained in a class that inherits from or is a member of class A. Private variables and methods can only be accessed from the same class.
I have read that the main differences between classes and structures (other than functions), is that class members default to private, whereas structure members default to public.
That implies that structure members can be private. My question is: Can you have private structure members? And if you can, what is the purpose of using private members? How would you even access them?
Yes structures can have private members, you just need to use the access specifier for the same.
struct Mystruct
{
private:
m_data;
};
Only difference between structure and class are:
access specifier defaults to private for class and public for struct
inheritance defaults to private for class and public for struct
How can you access them?
Just like you access private members of a class. i.e: they can only be accessed within the structures member functions and not in derived structure etc.
The only difference between struct and class is default access (with the exception of some weird template situations, see Alf's comments below). This means you can access private members in the same way as in a class:
struct foo {
int get_X() { return x; }
void set_X(int x_) { x = x_; }
private:
int x;
};
Whether you use struct or class, then, is purely a matter of style. I tend to use struct when all members are public (eg, if it's a functor class with no member variables and only public functions).
One thing that makes this useful is that you can also use the friend key word in structs, so private members can only be used and modified by those specific functions or classes or what not that you want to be able to modify it. This way the user can't modify those sections themselves. They won't even show up in the auto fill features, at least in visual studio.
I have a class A, which have a field val declared as private.
I want to declare a class B, that inherit from A and have an access to val.
Is there a way to do it on C++?
I want to do it because I need to overload some functions of A, without changing A code at all.
Thanks.
Quick answer: You don't. Thats what the protected key-word is for, which you want to use if you want to grant access to subclasses but no-one else.
private means that no-one has access to those variables, not even subclasses.
If you cannot change code in A at all, maybe there is a public/protected access method for that variable. Otherwise these variables are not meant to be accessed from subclasses and only hacks can help (which I don't encourage!).
Private members of a base class can only be accessed by base member functions (not derived classes). So you have no rights not even a chance to do so :)
class Base
public: can be accessed by anybody
private: can only be accessed by only base member functions (not
derived classes)
protected: can be accessed by both base member functions and derived
classes
Well, if you have access to base class, you can declare class B as friend class. But as others explained it: because you can, it does not mean it's good idea. Use protected members, if you want derived classes to be able to access them.
It is doable as describe in this Guru of the Week - GotW #76 - Uses and Abuses of Access Rights. But it's should be considered a last resort.
You need to define it as protected. Protected members are inherited to child classes but are not accessible from the outside world.
You can access the private members of a base class say A through an inherited member function of A
#include<iostream>
using namespace std;
class A{
int a;
public:
A(){};
A(int val){a=val;};
int get_a(){//To access a private variable it must be initialized here
a=10;
return a;
}
};
class B: public A{
int b;
public:
B(){};
B(int val){b=val;};
void get(){
cout<<get_a();
}
};
int main(){
A ob1(2);
cout<<ob1.get_a()<<endl;
B ob2(4);
ob2.get();
return 0;
}