Добрый день.
При чтении одной книги я встретил не совсем понятное для меня утверждение. Книга на английском, потому, конечно, можно сказать, что все упирается в незнание языка (да так оно и есть, этот язык С++

.Тем не менее, надеюсь на вашу помощь. Далее я буду вынужден привести цитату из книги и примерное содержание главы.
Глава называется
The Politically Correct Struct. В начале автор приводит пример, называя его C-trick
struct mumble{
char pc[1];
};
Начинается скучный пример с использованием такой структуры для хранения строки
struct mumble * pmumb1 = (mumble *)malloc(sizeof(mumble)) + strlen(pszStr) + 1;
strcpy(&mumble.pc,pszStr);
Далее автор совершенно резонно говорит о том, что в случае с классами, наличием виртуальных функций, наследования и т.п. – подобный такому код негоден вследствии неизвестного порядка размещения подобъектов и членов из секций с разным доступом.
Потом он рассказывает о наследовании структуры классом:
struct c_point{
//
};
class Point:public c_point{
//
};
void Some_Fun(point,point){…}
void Some_Fun(c_point, c_point){…}
И тут начинается непонятное:
This idiom is no longer recommended, however, because of changes to the class inheritance layout in some compilers (for example, the Microsoft C++ compiler (непонятно, о каком это он компиляторе говорит – книга 95 года)) in support of the virtual function mechanism. Composition, rather than inheritance, is the only portable method of combining C and C++ portions of a class ...
Итак, что он имеет в виду? Что в функцию Some_Fun(c_point, c_point) я не могу передавать объекты класса Point? Что из-за поддержки виртуальных функций данные этой структуры не будут расположены непрерывно и я не смогу нормально этот объект скопировать при передаче по значению? Так ли это? Или я неправильно понял? Если это действительно так, то чем от структур будут отличаться классы?
И еще.
Предположим, я структуру унаследовал виртуально. Как я понимаю, компилятор может поместить в нее некоторый указатель, чтобы найти полный объект (
кстати, может ли он это сделать при отсутствии в базовом классе виртуальных функций и/или баз ?). Предположим, объект такого класса я передам по значению в функцию, которая принимает структуру-базу. Могут ли здесь возникнуть проблемы – т.е. при копировании будет использоваться “неправильный ” объект, неправильный из-за наличия этого лишнего “указателя”?
Здравствуйте, Lorenzo_LAMAS, Вы писали:
LL>LL>struct mumble * pmumb1 = (mumble *)malloc(sizeof(mumble)) + strlen(pszStr) + 1;
LL>strcpy(&mumble.pc,pszStr);
LL>
Насколько я понял, здесь происходит выделение памяти под одну структуру mumble. Возвращенный malloc указатель мы складываем с длиной pszStr и присваиваем pmumb1. strcpy наверняка перезапишет выделенный malloc буфер. наверно ты неправильно расставил скобки.
LL>LL>This idiom is no longer recommended, however, because of changes to the class inheritance layout in some compilers (for example, the Microsoft C++ compiler (непонятно, о каком это он компиляторе говорит – книга 95 года)) in support of the virtual function mechanism. Composition, rather than inheritance, is the only portable method of combining C and C++ portions of a class ...
LL>Итак, что он имеет в виду? Что в функцию Some_Fun(c_point, c_point) я не могу передавать объекты класса Point? Что из-за поддержки виртуальных функций данные этой структуры не будут расположены непрерывно и я не смогу нормально этот объект скопировать при передаче по значению? Так ли это? Или я неправильно понял? Если это действительно так, то чем от структур будут отличаться классы?
Если в классе Point заводится таблица виртуальных методов, то гарантировать какое-либо расположение объекта типа Point никто не может. Более того, какие-то гарантии предоставляются только для POD типов (это лучше поискать по форуму, уже обсуждалось). Почему он говорит, что Composition, rather than inheritance,
is the only portable method of combining C and C++ portions of a class, совершенно непонятно...Гарантии, что
// при таком определении
struct A { int x, y; }
struct B { A a; virtual void f(); }
void f()
{
B b;
std::cout << &b << " " << &b.a;
// выведет два одинаковых числа
}
тебе, afaik, никто не даст.
LL>Предположим, я структуру унаследовал виртуально. Как я понимаю, компилятор может поместить в нее некоторый указатель, чтобы найти полный объект
Он скорей помещает указатель на нее в полный объект. (наверно)
LL>([b]кстати, может ли он это сделать при отсутствии в базовом классе виртуальных функций и/или баз ?). Предположим, объект такого класса я передам по значению в функцию, которая принимает структуру-базу. Могут ли здесь возникнуть проблемы – т.е. при копировании будет использоваться “неправильный ” объект, неправильный из-за наличия этого лишнего “указателя”?
проблем возникнуть не должно.
Это — одна из бызовых гарантий (Barbara Liskow). Объект произодного класса может использоваться везде, где требуется объект базового класса.