#c #c 11
#c #c 11
Вопрос:
Компиляция моего кода, содержащего этот класс:
class Dessin
{
private:
vector<Figures*>T;
public:
void ajouteFigure(const Figuresamp; f) const
{
for(auto element: T)
{
T.push_back(f);
}
}
};
выдает ошибку:
[Ошибка] нет соответствующей функции для вызова ‘std::vector::push_back(const Цифрыamp;) const’
Это то, что я должен делать в main()
Dessin s;
s.ajouteFigure(Cercle(1.1));
Почему это не сработает?
Комментарии:
1. @AlexD, хотя и ошибочный с самого начала.
2. Вместо этого не храните необработанные указатели в a
std::vector
— usestd::vector<std::unique_ptr<Figure>>
.3. @AlexD Я пробовал это, это не работает. Та же ошибка
4. @AlexD Это работает, спасибо. Могу ли я узнать, почему именно?
5. Этот код настолько неработающий, что никакой ответ вам не поможет.
Ответ №1:
Предполагая Cercle
, что это имя класса, вы пытаетесь ввести значение, в котором ожидается указатель.
Чтобы «исправить» ошибку, вы должны изменить свой ajouteFigure
прототип, чтобы принимать Figures
указатели и неконстантные this
:
void ajouteFigure(Figures* f)
Затем вы должны вызвать его, передавая указатель на Figures
объект, т.Е. Созданный с new
помощью выражения:
s.ajouteFigure(new Cercle(1.1));
При этом этот код кажется бессмысленным. Вы добавляете указатель столько раз, сколько у вас есть элементов в векторе (который всегда равен 0 в приведенном вами примере).
Использование необработанных указателей также не рекомендуется, вы должны использовать интеллектуальные указатели, такие как std::unique_ptr
, хотя это нарушило бы текущий код.
Рассмотрим этот, менее неправильный, пример:
class Dessin
{
private:
vector<unique_ptr<Figures>> T;
public:
void ajouteFigure(unique_ptr<Figures> f)
{
T.push_back(move(f)); // just once
}
};
и на сайте вызова:
Dessin s;
s.ajouteFigure(make_unique<Cercle>(1.1)); // C ≥14
или, если вы не можете использовать C 14:
Dessin s;
s.ajouteFigure(unique_ptr<Figures>(new Cercle{1.1}));
Комментарии:
1. Этот вопрос помечен как c 11, вероятно, вам следует предоставить альтернативу
std::make_unique
на случай, если OP еще не использует c 14.2. Добавлен @Archieposopofbanterbury.
Ответ №2:
Просто чтобы добавить к этому, я думаю, вам было бы лучше сделать это шаблонной функцией и создать нужный объект внутри функции с аргументами конструктора, переданными в качестве параметров функции.
Таким образом, вам не нужно создавать std::unique_ptr
или использовать new
каждый раз, когда вы вызываете функцию.
Вот базовая реализация:
class Dessin{
public:
template<typename T, typename ... Args>
void ajouteFigure(Args amp;amp;... args){
figures.emplace_back(new T(std::forward<Args>(args)...));
}
private:
std::vector<std::unique_ptr<Figures>> figures;
};
Тогда использование класса менее подвержено ошибкам:
int main(){
Dessin d;
d.ajouteFigure<Cercle>(1.1);
}