Как вызвать точный метод производного класса?

Я попробовал вышеуказанное решение, но я счел его непригодным для больших объемов данных. Затем я обнаружил функцию потока:

MongoClient.connect("...", function(err, db){
    var c = db.collection('yourCollection');
    var s = c.find({/* your query */}).stream();
    s.on('data', function(doc){
        c.update({_id: doc._id}, {$set: {name : doc.firstName + ' ' + doc.lastName}}, function(err, result) { /* result == true? */} }
    });
    s.on('end', function(){
        // stream can end before all your updates do if you have a lot
    })
})
0
задан exru 15 January 2019 в 10:38
поделиться

3 ответа

  • Во-первых, как уже отмечали другие,

§13.1, где в стандарте обсуждаются объявления, которые не могут быть перегружены состояниями -

Объявления параметров, которые отличаются только при наличии или отсутствии const и / или volatile эквивалентны. Таким образом, спецификаторы const и volatile для каждого типа параметра игнорируются [...]

В этом способе игнорируются только спецификаторы const и volatile на внешнем уровне спецификации типа параметра; Спецификаторы типа const и volatile, скрытые в спецификации типа параметра, имеют большое значение и могут использоваться для различения объявлений перегруженных функций. [...]

при определении, какая функция объявляется, определяется или вызывается. В частности, для любого типа T «указатель на T», «указатель на const T» и «указатель на изменчивый T» считаются различными типами параметров, как и «ссылка на T», «ссылка на const T» и «ссылка на изменчивый T».

Следовательно,

void validateAttribute(Model &model, std::string &attribute) override;

не совпадает с

void validateAttribute(Model &model, const std::string &attribute);
  • Во-вторых, вы можете избегайте таких ошибок, если у вас есть C++11 или новее с использованием ключевого слова override в объявлении функции, как показано ниже.

с переопределением ключевое слово, этот код не позволит вам скомпилировать, если сигнатура функции в производном классе не совпадает с сигнатурой в базовом классе!

class RequiredValidator : public Validator
{
public:
    std::string m_name = "RequiredValidator";

    void validateAttribute(Model &model, std::string &attribute) override;
    ~RequiredValidator();
    std::string name() const;
};

РЕДАКТИРОВАТЬ: ps override требуется ключевое слово virtual. Следовательно, [1117 ]

virtual void validateAttribute(Model &model, std::string &attribute) override;
0
ответ дан Joey Mallone 15 January 2019 в 10:38
поделиться

Посмотрите внимательно на то, как вы определили void RequiredValidator::validateAttribute()

Вы можете заметить, что подпись немного отличается от базовой (std::string &attribute не const)

есть ключевое слово override, что помогло бы компилятору ловить эти типы опечаток.

0
ответ дан Eyal Cinamon 15 January 2019 в 10:38
поделиться

Удаление всего ненужного кода давайте рассмотрим сигнатуры как базового, так и унаследованного классов:

class Validator {
public:
    virtual void validateAttribute(Model &model, const std::string &attribute);
};

class RequiredValidator : public Validator {
public:
    void validateAttribute(Model &model, std::string &attribute);
};

В базовом классе ::validateAttribute() у вас есть для его параметров Model& model и const std::string& attribute, и в производном классе ::validateAttribute() у вас есть для его параметров Model &model и std::string& attribute.

Конфликт здесь const std::string& и std::string&. Либо сделайте две функции точно совпадающими заранее, либо в вашем случае, потому что вы пытаетесь использовать полиморфизм, который вы можете в своем производном классе исправить, выполнив следующее:

/*virtual*/ void validateAttribute( Model& model, std::string& string ) override;

Ключевое слово override здесь сгенерирует компилятор ошибка для объяснения вашей проблемы. Не забудьте также добавить virtual, если вы планируете наследовать от этого производного класса.

0
ответ дан Francis Cugler 15 January 2019 в 10:38
поделиться
Другие вопросы по тегам:

Похожие вопросы: