Reputation: 329
I'm asking this about C++ since I'm familiar with that but the question really explains itself: is there a language in which we can derive a class and make it occupy less space in memory than the original class?
This question is more of a gimmick than an actual problem I'm trying to solve, but I could imagine that some really high-performant code could benefit from this kind of memory optimization:
Suppose we have:
class Person {
std::string name;
unsigned int age;
}
class PersonNamedJared {
}
In theory, we don't need a field "name" in this subclass since it'll always be "Jared", which could allow for better memory efficiency.
Is the only way to make this happen by replacing the 'name' field in Person
with a get_name()
function that we simply override in PersonNamedJared
to always return "Jared"? How would we still make the name variable in the base class?
I know this example is really bad practice, but it's the best I could come up with. I think there are legitimate reasons to implement this kind of pattern.
Upvotes: 4
Views: 1336
Reputation: 238361
Can a derived class be smaller than its parent class?
No. A derived class always contains a base class sub object. An object can never be smaller than its sub objects, so a derived class can never be smaller than its base.
Is the only way to make this happen by replacing the 'name' field in Person with a get_name() function that we simply override in PersonNamedJared to always return "Jared"?
That would be one way to achieve it.
How would we still make the name variable in the base class?
You couldn't have a member variable in a base that you don't want to be in the derived class.
You could for example use multiple inheritance so that you do have a base with the variable in some derived classes. Something like this:
struct Person {
unsigned int age;
virtual std::string name() = 0;
...
struct Named {
std::string name;
};
struct NamedPerson : Person, private Named {
std::string name() override {
return name;
}
};
struct JaredPerson : Person {
std::string name() override {
return "Jared";
}
};
Here, there is a base with the variable, but Jared does not inherit that particular base.
Upvotes: 6
Reputation: 16873
The answer should be clear if you make use of polymorphism. That is, take advantage of the language features that let you view an object of a derived type as one of a base type. Assume Person
is a public base of PersonNamedJared
and consider the following code.
PersonNamedJared Jared;
Person * Pointer = &Jared;
std::cout << Pointer->name << " is " << Pointer->age << " years old.";
This is valid, but how could this code possibly work if PersonNamedJared
lacked a name
field?
As a rule of thumb, if you have a legitimate reason to want a derived class to be smaller than its base class, then there is probably something wrong with your class design.
With regards to could there be a language that has this feature, I think it is possible, but rather awkward. You could – in a hypothetical language – blur the line between data members and function members by allowing the identifier name
to represent (virtual) data in the base class but a function in derived classes. So a derived class could provide a function called name
, overriding the base class version. You could block explicit references to the base class version of name
when dealing with an object of derived type. With enough requirements and prohibitions, the name
field would inaccessible in certain derived class objects, hence it would not be needed by them. In that case, the name field could be omitted. (However, I am not aware of any language that permits this stringent setup.)
On the other hand, this setup feels like it runs counter to the principles of inheritance. Even if a language allowed this setup, I would prefer better class design.
Upvotes: 1
Reputation: 51845
Can a derived class be smaller than its parent class?
In C++, No!
Even if you try to replace a member of the base class with a smaller member in the derived class (by using the same name), the base class member is still there (it's just harder to access). This code will demonstrate that, with the derived class actually adding to the size of the base:
#include <iostream>
class A {
public:
double q[200];
};
class B : A {
public:
double q[100]; // Can we replace base array with a smaller one?
};
int main()
{
std::cout << sizeof(A) << std::endl; // -> 1600 = 200 * sizeof(double)
std::cout << sizeof(B) << std::endl; // -> 2400 ADDS 100 more doubles!
return 0;
}
Upvotes: 2
Reputation: 15868
No.
Inheriting from a class means that you include all its member variables, it's parent class[s] member variables, plus whatever your own class contains.
To put it another way, child classes are a superset of parent classes. (with the exception of an empty child class)
Even private members are still there taking up space, it's just a compiler error to try and access them.
Upvotes: 2