Мне нужно знать, зачем Вы хотите такое сделать, иначе не понятно, почему пытаетесь использовать перегрузку типов (которой нет).
Если Вам нужно полиморфное поведение - воспользуйтесь виртуальными функциями.
Теперь разберем Ваш код в одном месте:
typedef float custom;
Здесь не происходит ничего иного, кроме как объявления имени в области видимости класса B. Как я говорил выше переопределять типы нельзя, и от написанного Вами кода, тип custom в А не поменяется. Иными словами у вас будет два типа:
A::custom = int
B::custom = float
Что Вам нужно сделать:
class I
{
public:
virtual void print() = 0;
};
class A : public I
{
public:
virtual void print() override
{
std::cout << num;
}
private:
int num = 1;
};
class B : public I
{
public:
virtual void print() override
{
std::cout << num;
}
private:
float num = 2.f;
};
Иерархии из трех классов можно избежать, написав простой шаблон:
template <typename T>
class A
{
public:
void print()
{
std::cout << val;
}
private:
T val;
};