I want to do make a public member in a base class private in a derived class, like this:
class A {
public:
int x;
int y;
};
class B : public A {
// x is still public
private:
// y is now private
using y;
};
But apparently "using" can't be used that way. Is there any way to do this in C++?
(I can't use private inheritance because there are other members and functions of A that must still be public.)
Yes, using declaration technically allows you to do so.
You have to use using A::y instead of using y
However please seriously evaluate if doing this makes a design sense.
Few observations:
Your class should not have public data. That should be avoided as far as possible. If you stick to this design principle, you may not have a need to make it private in derived class.
Stick to LSP. If a base class has public method, and unless you are doing private inheritance, clients will be confused if the derived class makes the base class method private with such using declarations.
Short answer: no. Liskov substitution and the nature of public inheritance demands that everything that you can do with an A (i.e. its public members) can also be done by B. That means you can't hide a public method.
If you're trying to hide public fields, there isn't much you can do. To "hide" public methods, you could do something like:
class B {
// x is still public
int x() { return a.x(); }
private:
A a;
// y is now private since you didn't add a forwarding method for it
};
Related
I have this large class that I want to separate into different classes. The reason why it was large because the class had many private variables and functions that are needed to run the program. I was tired of scrolling down the 1000+ lines of code trying to add or edit code. I am wondering if it is possible for the classes to interact with one base class that includes all the private/protected variables it needed to operate, or simply have them as global variables.
I am aware of inheritance as I tried having the separate classes be derived from the base class, by doing something similar to this:
#include <iostream>
class Base {
public:
void sayPrivateVar() {
std::cout << privateVar;
}
protected:
std::string privateVar = "I am a protected variable!";
};
class Derived : public Base {
public:
void manip() {
base->privateVar = "That was updated from a derived class";
}
private:
Base* base;
};
int main() {
Base base;
Derived derived;
derived.manip();
base.sayPrivateVar();
return 0;
}
EDIT: Without creating another object inside a class.
it depends on your class and what you have in it. It is often better not have inheritance because derived classes may then get member variables that they don't need. There are a few other ways you can do. One way would be to group you private variables in different classes and then have member variables in the first class.
E.g.
class X {
int x;
int y;
int angle;
...
};
becomes
class XYVector;
class X {
XYVector v;
};
class XYVector
{
int x;
int y;
int angle;
};
You can continue in this direction and instead of making them concrete class like XYVector above have them as interfaces : to have it more elaborate and flexible check out https://en.wikipedia.org/wiki/Composition_over_inheritance
At any rate: avoid having globally declared variables.
This is a good question and the answer is absolutely. Inheritance is actually a very good solution in this particular context since that is how object code shares it's scope with other classes. One important thing to note here is that how you call your derived class is important because the inherited scope is set along with the derived class (i.e. declaring it public base would inherit the public and protected methods as opposed to declaring it private which would give the derived class even more access!)
I have an abstract class base with private member variable base_var. I want to create a derived class, which also has base_var as a private member.
To me, this seems like an obvious thing you would want to do. base is abstract so it will never be instantiated. The only time I will create a base-object is if it is actually a derived object, so obviously when I give ´base´ a private member variable, what I am really trying to do is give that variable to all of its derived objects.
However, the below diagram seems to suggest that this is not doable with inheritance?
Why not? What would then even be the point of having private stuff in an abstract class? That class will never be instantiated, so all that private stuff is essentially useless?
However, the below diagram seems to suggest that this is not doable with inheritance?
Correct, private members of a class can not be accessed by derived classes. If You want a member of a class to be accessible by its derived classes but not by the outside, then You have to make it protected.
Why not? What would then even be the point of having private stuff in an abstract class? That class will never be instantiated, so all that private stuff is essentially useless?
Even an abstract class can have member functions which act on a (private) member variable. Consider (somewhat silly example, but well):
class MaxCached
{
private:
int cache = std::numeric_limits<int>::min();
public:
bool put(int value)
{
if (value > cache)
{
cache = value;
return true;
}
return false;
}
int get() const
{
return cache;
}
virtual void someInterface() const = 0;
};
Deriving from this class gives You the functionality of the base class (put and get) without the danger of breaking it (by for example writing a wrong value to cache).
Side note: Above is a purely made up example! You shouldn't add such a cache (which is independent of Your interface) into the abstract base class. As it stands the example breaks with the "Single Responsibility Principle"!
Just because a class is abstract doesn't mean there cannot be code implemented in that class that might access that variable. When you declare an item in a class to be private, the compiler assumes you had a good reason and will not change the access just because it there is a pure virtual function in the class.
If you want your derived classes to have access to a base class member declare the member as protected.
I have an abstract class base with private member variable base_var
class foo {
public:
virtual void a_pure_virtual_method() = 0;
int get_var() { base_var; }
virtual ~foo(){}
private:
int base_var;
};
Note that a class is said to be abstract when it has at least one pure virtual (aka abstract) method. There is nothing that forbids an abstract class to have non-pure virtual or even non-virtual methods.
I want to create a derived class, which also has base_var as a private member.
class derived : public foo {};
To me, this seems like an obvious thing you would want to do.
Sure, no problem so far.
The only time I will create a base-object is if it is actually a derived object, so obviously when I give ´base´ a private member variable, what I am really trying to do is give that variable to all of its derived objects.
Still fine.
Why not?
You are confusing access rights that are display in the image you included with the mere presence of the members in the derived. The derived class has no access to members that are private in the base class. Period. This is just according to the definition of what is private.
What would then even be the point of having private stuff in an abstract class? That class will never be instantiated, so all that private stuff is essentially useless?
It is not useless at all. Derived classes inherit all members, they just cannot access all of them. The private stuff is there you just cannot access it directly. Thats the whole point of encapsulation. Consider this example:
class bar : public foo {
void test() {
std::cout << base_var; // error base_var is private in foo
std::cout << get_var(); // fine
}
};
I have created two classes A and B where B inherits from class A. As you can see, I have a vector in class A that is currently under the protected section of the class. I am unsure if using protected is bad practice?
#include <vector>
class A
{
public :
A();
protected:
std::vector <std::string> a;
};
class B : A
{
public :
B();
void accessVector()
{
a.size();
}
private:
};
When A makes a data member a protected, it is offering the following guarantee to all classes that derive from it:
"You may do anything you like to a without telling me. This includes appending to it, modifying its contents, removing items, sorting it, moving from it, moving to it and otherwise making its state undefined and/or unknowable to me".
Remember that anyone may create a class that derives from A.
For this reason, to all intents and purposes, a protected member is a public member, since a derived class may simply say the following:
public:
using A::a;
Starting here and working forward, you'll find that there are only two sensible use-cases for protected:
When a base class defines a virtual member function that may need to be called from an overridden version of the same function in a derived class.
When the base class wants to expose 'data as interface' to a derived class, but not to the world.
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.
Sorry if the question is silly. I come from java background.
In the following code, base_list is a parent class of SqlAloc, but what's the meaning of public memory?
class base_list :public memory::SqlAlloc
{
protected:
list_node *first,**last;
uint32_t elements;
public:
};
Memory is probably a namespace (kind of like an outer class) in which SqlAlloc is defined.
C++ has both public and private inheritance (protected, too, actually.) public inheritance is just like Java inheritance; in private inheritance, though, code outside the derived class doesn't know about the base class. It's a way to inherit implementation without inheriting type. In Java, you can only do both.
memory is either a namespace or a class (struct). public means that all member functions and member data which were declared in SqlAlloc class(struct) as public and protected will be visible in base_list as public and protected.
base_list is publicly deriving from SqlAlloc which is either a namespace-class, or nested-class, depending upon what memory is - which could be either a namespace or a class.