Ошибка компоновщика при сборке с MSVC 2015 (другие CC в порядке)

Вот MCVE:

#include <iostream>
#include <string>

using namespace std;

class Obj {
public:
    Obj() { cout << "Obj()" << endl; }
    ~Obj() { cout << "~Obj()" << endl; }
    void* operator new(size_t sz){
        return ::operator new(sz);
    }
    void operator delete(void* p) {
        ::operator delete(p);
    }
private:
    friend class MyClass;
    void* operator new(size_t, void*);
    void operator delete(void*, size_t);
};

class MyClass {
public:
    MyClass() : m_(new Obj) {
        cout << "MyClass()" << endl;
    }
    ~MyClass() {
        cout << "~MyClass()" << endl;
        delete m_;
    }
private:
    const Obj * m_;
};

int main()
{
    cout << "Started" << endl;
    MyClass o;
    cout << "Finished" << endl;
    return 0;
}

Здание с MSVC 2015 (14.0):

error LNK2019: unresolved external symbol "private: static void __cdecl Obj::operator delete(void *,unsigned int)" (??3Obj@@CAXPAXI@Z) referenced in function __unwindfunclet$??0MyClass@@QAE@XZ$0

Сборка с MSVC 2013 (12.0): ОК

Сборка с GCC 5.2: ОК

Вопросы:

Зачем?

Как исправить / обойти?

PS

Исходный файл в проекте QtScript.

1 ответ

Решение

Учитывая критические изменения в Visual C++ 2015, я склоняюсь к следующему решению:

class Obj {
...
private:
    friend class MyClass;
    void* operator new(size_t, void*);
#if defined(_MSC_VER) && _MSC_VER >= 1900
    enum class Obj_tag : size_t {};
    void operator delete(void*, Obj_tag);
#else
    void operator delete(void*, size_t);
#endif
};

Итак, следующий код

#ifdef ERROR_TEST
char buf[1024] = { 0 };
Obj * o1 = reinterpret_cast<Obj*>(buf);
new (o1) Obj;
#endif
MyClass o2;

компилируется одинаково как с MSVC 2012, так и с MSVC 2015. (Когда ERROR_TEST определяется там error C2248: 'Obj::operator new': cannot access private member declaredа когда нет - все ок)

Другие вопросы по тегам