我不确定提问者期待什么答案,但这里有一些可能的解决方案:
使“A”成为指针:
//Only takes 4 or 8 bytes (32 bit vs 64 bit code) for 'A', regardless of 'A's actual size, but must point to an 'A' located elsewhere in memory with the full size.
class B
{
A *a; //Only 4 bytes.
int b;
};
使'A'静态:
//Doesn't assume any of 'A's size, but all instances of 'B' shares a single instance of 'A'.
class B
{
static A a;
int b;
};
将 'A' 传递给 'B' 的函数:
//Pass in the reference to 'a' when needed, so multiple 'B's can share the same 'a' explicitly when desired.
class B
{
void q(A &a) { this->b + a.a; return a.g(); }
};
让'A'和'B'没有虚拟表(可能是面试官的观点)
//By not having virtual functions, you save the (really small) cost of 4 bytes (8 bytes on 64 bit machines)
class A
{
public:
int f() { }; //Not virtual
int a;
}
class B : public A
{
public:
int g() { }; //Not virtual
int b;
}
它仍然花费您 A::a 的大小,并且除非您在 B 中重新使用 'a' 而不是使用 B::b,否则您无法避免这 4 个字节。并且重新使用一个变量来完全表示其他东西可能是非常糟糕的编程习惯的迹象。
合并 A'a 和 B 的变量并将函数放在一个类中
class AB //Only 4 bytes total
{
public:
union
{
int a;
int b;
};
void f();
void g();
};
关于这个的坏主意是,您必须跟踪是否应该访问“a”或“b”,因为它们都占用相同的 4 字节内存,并且它们不能同时使用它同时。
另一个不好的地方是,这表明这个类有太多的责任。是A还是B?如果两者兼而有之,那么最重要的问题应该是“为什么两者兼而有之?”。它应该有一个单一的职责,而不是混合用途的单体。
将“A”设为模板,并继承自A<B>
:
template<typename TypeB>
class A
{
int a;
};
//Saves the cost of the virtual table... not that that really matters.
class B : public A<B>
{
int b;
};
最后一个被称为'奇怪的重复模板模式'(CRTP),其想法是继承的' A<B>
'可以从'B'调用访问变量和函数(如果你将B的'this'指针传递给A的构造函数),并且'B ' 可以直接从 ' A<B>
' 访问变量和函数。
您继承自为“B”生成的模板“A”的编译时生成版本。