C ++ 11, §9 / 7:
A класс стандартной компоновки - это класс, который:
- не имеет нестатических членов-данных типа нестандартного класса (или массива таких типов) или ссылки,
- не имеет виртуальных функций и виртуальных базовых классов,
- имеет одинаковый контроль доступа для всех нестатических элементов данных,
- не имеет базовых классов нестандартной компоновки,
- либо не имеет нестатических элементов данных в наиболее производном классе и не более одного базового класса с нестатическими элементами данных, либо не имеет базовых классов с нестатическими элементами данных, и
- не имеет базовых классов того же типа, что и первый нестатический элемент данных.
Итак, есть ли способ сделать класс со стандартным макетом не подлежащим копированию? Если да, то как?
Частное наследование от boost :: noncopyable не будет работать, потому что это сделало конструктор копирования закрытым (следовательно, не стандартной компоновкой). Реализация boost :: noncopyable выглядит следующим образом:
class noncopyable
{
protected:
noncopyable() {}
~noncopyable() {}
private: // emphasize the following members are private
noncopyable( const noncopyable& );
const noncopyable& operator=( const noncopyable& );
};
Из-за закрытого раздела это не стандартный класс макета. Также я уверен, что частное наследование нарушает какое-либо стандартное правило размещения.
#include <boost/noncopyable.hpp>
#include <iostream>
const int N = 50;
struct A
{
int data[N];
};
struct B : private boost::noncopyable
{
int data[N];
};
struct C
{
A data[10];
};
struct D : private boost::noncopyable
{
B data[10];
};
int main() {
std::cout<<sizeof(A)<<std::endl;
std::cout<<sizeof(B)<<std::endl;
std::cout<<sizeof(C)<<std::endl;
std::cout<<sizeof(D)<<std::endl;
}
Вывод:
200
200
2000
2004
Приведенный выше пример показывает, что частное наследование от boost::noncopyable
изменяет класс на НЕ совместимый со стандартным макетом.
Я не уверен, является ли это ошибкой g ++ (я использую g ++ 4.6.1), или стандарт каким-то образом нарушен.