Запретить сериализацию объекта напрямую (не через указатель), если у него нет конструктора по умолчанию.

Недавно я использовал save_construct_data() и load_construct_data(), когда мне нужно сериализовать объект без конструктора по умолчанию. Так как нет смысла делать:

MyObject a; // can't do this because there is no default constructor
archive >> a;

мы должны сделать:

MyObject* aPointer;
archive >> a;

который вызывает load_construct_data() перед serialize(). Однако, конечно, это работает только в том случае, если объект был сериализован с использованием save_constructor_data(), который вызывается только в том случае, если он написан как указатель, например.

MyObject a(1,2);
MyObject aPointer = &a;
archive << aPointer;

Все это работает нормально, но кажется, что archive << a; работает нормально, но логически не имеет смысла, так как его никогда нельзя будет десериализовать. Есть ли способ запретить этот вызов, чтобы объекты (возможно, члены класса большего класса и т. д.) случайно не записывали Object не через указатель?

------------- РЕДАКТИРОВАТЬ ----------

Пытаясь последовать предложению SergeyA, я сделал следующую демонстрацию. К сожалению, кажется, что данные не читаются правильно?

#include <fstream>

#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/serialization/serialization.hpp>

class Point
{
private:
    friend class boost::serialization::access;

    template<class TArchive>
    void serialize(TArchive& archive, const unsigned int version)
    {
        archive & mX;
        archive & mY;
    }

public:
    template<class TArchive>
    Point(TArchive& archive)
    {
        serialize(archive, 0);
    }

    Point(){} // Only provided to test Works()

    Point(const float x, const float y) : mX(x), mY(y) { }

    float mX = 4;
    float mY = 5;
};

void Works()
{
    std::cout << "Works():" << std::endl;
    Point p(1,2);

    std::ofstream outputStream("test.archive");
    boost::archive::text_oarchive outputArchive(outputStream);
    outputArchive << p;
    outputStream.close();

    // read from a text archive
    std::ifstream inputStream("test.archive");
    boost::archive::text_iarchive inputArchive(inputStream);
    Point pointRead;
    inputArchive >> pointRead;

    std::cout << pointRead.mX << " " << pointRead.mY << std::endl;
}

void DoesntWork()
{
    std::cout << "DoesntWork():" << std::endl;
    Point p(1,2);

    std::ofstream outputStream("test.archive");
    boost::archive::text_oarchive outputArchive(outputStream);
    outputArchive << p;
    outputStream.close();

    std::ifstream inputStream("test.archive");
    boost::archive::text_iarchive inputArchive(inputStream);
    Point pointRead(inputArchive);

    std::cout << pointRead.mX << " " << pointRead.mY << std::endl;
}

int main()
{
    Works(); // Output "1 2"
    DoesntWork(); // Output "0 0"
    return 0;
}

person David Doria    schedule 29.02.2016    source источник
comment
Неправильный дизайн. Если вы хотите запретить объекты по умолчанию, просто реализуйте конструктор десериализации. Но не вводите указатели, когда они не нужны!   -  person SergeyA    schedule 29.02.2016
comment
Вы, вероятно, можете использовать черты типа, если вы работаете в C++11: en.cppreference .com/w/cpp/types/is_default_constructible   -  person Steve    schedule 29.02.2016
comment
@SergeyA Что вы подразумеваете под десериализующим конструктором?   -  person David Doria    schedule 29.02.2016
comment
Это конструктор, который возьмет ваш «архивный» объект и десериализует его.   -  person SergeyA    schedule 29.02.2016
comment
@SergeyA Значит, в save/load_constructor_data() вообще нет необходимости?   -  person David Doria    schedule 29.02.2016
comment
@DavidDoria, я не уверен, каково значение этих функций.   -  person SergeyA    schedule 29.02.2016
comment
@SergeyA А что потом происходит в моей функции-члене serialize()? Если у меня есть архив, и я хочу archive << myClass;, то здесь будет вызываться serialize(). Я думаю, было бы просто невозможно вызвать MyClass myClass; archive >> myClass;, потому что нет конструктора по умолчанию, поэтому я бы просто вызвал serialize(archive); из сериализующего конструктора?   -  person David Doria    schedule 29.02.2016
comment
@SergeyA Этот шаблон имеет смысл, но он, кажется, записывает в архив два лишних нуля? См. отредактированный вопрос с примером. Вывод Works() — 1 2, а вывод DoesntWork() — 0 0. Можете ли вы объяснить разницу в этих двух функциях?   -  person David Doria    schedule 01.03.2016
comment
Я добавил вопрос с более подходящим заголовком: stackoverflow.com/questions/35722135/ Ответ на текущий вопрос, как указал СергейА, не делайте этого и предпочитайте десериализующий конструктор (как только мы заставим его работать :)).   -  person David Doria    schedule 01.03.2016