Вы, кажется, объединяете две общие конструктивные особенности:
1) AInternal - это "прыщ". Это обеспечивает лучшую инкапсуляцию, например, если вам нужно добавить новое поле в AInternal, тогда размер AImpl не изменится. Это нормально.
2) A - это базовый класс, используемый для обозначения интерфейса. Поскольку вы говорите о повышении и понижении, я предполагаю, что вам нужен динамический полиморфизм, что означает, что у вас будут функции, которые передают указатели или ссылки на A, и во время выполнения ссылки будут фактически иметь тип AImpl. Это также хорошо, за исключением того, что деструктор А должен быть либо виртуальным и общедоступным, либо не виртуальным и защищенным.
Я не вижу других проблем с дизайном этого кода. Конечно, вам действительно нужно определить интерфейс A, добавив в него некоторые чисто виртуальные функции-члены, которые вы реализовали в AImpl. Предполагая, что вы планируете это сделать, нет ничего плохого в использовании пустого базового класса для целей, которые в Java обслуживаются интерфейсами (если вы знаете Java). Как правило, у вас есть какая-то фабрика, которая создает объекты AImpl и возвращает их по указателю или по ссылке на A (следовательно, повышает их). Если клиентский код собирается создавать объекты AImpl напрямую, то это тоже может быть хорошо, и на самом деле вам может вообще не понадобиться динамический полиморфизм. Вы могли бы вместо этого войти в шаблоны.
Чего я не вижу, так это того, почему вам когда-нибудь пришлось бы опускаться (то есть, бросить A * на AImpl *) Обычно это плохие новости. Таким образом, в вашем дизайне могут быть некоторые проблемы, которые можно выявить, только показав нам больше определений классов и клиентский код, который фактически использует A и AImpl.