У меня есть заголовочный файл foo.h
, подобный этому (несвязанные вещи опущены):
#pragma once
#include <memory>
class Bar;
struct Foo
{
std::shared_ptr<Bar> getBar();
std::shared_ptr<const Bar> getBar() const
{
return const_cast<Foo*>(this)->getBar();
}
};
Неконстантная перегрузка getBar()
реализована в файле .cpp, который также содержит полное определение Bar
.
Когда foo.h
включается из другого файла (который не видит определения Bar
), VS 2010 выдает мне следующее предупреждение:
warning C4150: deletion of pointer to incomplete type 'Bar'; no destructor called
на константной перегрузке getBar()
(или на самом деле на чем-то глубоком в стандартной библиотеке, созданном из этой перегрузки).
Мой вопрос заключается в том, можно ли безопасно игнорировать это предупреждение.
На мой взгляд, в getBar() const
вызываются две функции-члена std::shared_ptr<Bar>
: конструктор преобразования и деструктор.
// converting constructor
template <class Y>
std::shared_ptr<const Bar>::shared_ptr(std::shared_ptr<Y> &&r)
Это используется для инициализации возвращаемого значения getBar() const
из возвращаемого значения getBar()
. Здесь не указаны какие-либо предварительные условия (C++11 27.2.2.1 §20-22), которые потребуют выполнения Y
(в моем случае Bar
).
// destructor
std::shared_ptr<const Bar>::~shared_ptr()
27.2.2.2 В §1 указано, что когда уничтожаемый общий указатель пуст, побочные эффекты отсутствуют.
Я понимаю, почему я получаю предупреждение - код деструктора также должен заботиться о ситуации, когда delete
должен вызываться для сохраненного указателя, и этот код действительно удалит неполный тип. Но, насколько я понимаю, в моей ситуации до него невозможно добраться, так что getBar() const
в безопасности.
Я прав, или я пропустил вызов или что-то, что могло заставить getBar() const
фактически удалить неполный тип?
const_cast<Foo*>(this)->getBar();
- это ПЛОХОЙ трюк - вам лучше вызывать константную версию из неконстантной версии. - person ikh   schedule 20.08.2014*this
, вы облажались. В вашем случае, если версия const возвращает указатель на что-то фактически объявленноеconst
, вы облажались. У обоих есть недостатки, вашему просто нужно одно дополнительное заклинание. - person Angew is no longer proud of SO   schedule 20.08.2014*this
в неконстантной перегрузке. - person Angew is no longer proud of SO   schedule 20.08.2014*this
, то функцию следует сделать константной. К сожалению, теперь у вас есть две константные функции! - person Neil Kirk   schedule 20.08.2014std::vector::at()
также не изменяет сам векторный объект, и у него все еще есть неконстантная перегрузка. Такая же ситуация здесь. - person Angew is no longer proud of SO   schedule 20.08.2014