#c #constructor #call
#c #конструктор #вызов
Вопрос:
Я пытаюсь создать временный объект C для того же самого быстрого вызова в конструкторе и ничего больше.
По какой-то причине это не работает
Вот код:
typedef std::vector<std::string> string_vec_t;
//-------------------------------------------------------------------------
struct visit_items
{
virtual void action(std::string *s) = 0;
};
void items_visitor(visit_items *v)
{
string_vec_t l = { "1", "2", "3", "4" };
for (auto amp;s: l)
v->action(amp;s);
}
struct my_visit_items: visit_items
{
public:
string_vec_t *r;
my_visit_items(string_vec_t *r /*, int */): r(r)
{
items_visitor(this);
}
virtual void action(std::string *s) override
{
r->push_back(*s);
printf("visited: %sn", s->c_str());
}
};
//-------------------------------------------------------------------------
int main(int argc)
{
string_vec_t r;
r.push_back("1");
my_visit_items(amp;r /*, 0 */);
return -1;
}
Если у меня есть ctor, принимающий дополнительный аргумент, то никаких проблем. Но в нынешнем виде это не работает, и я не понимаю причину ошибки:
1>error C2040: 'r': 'my_visit_items amp;' differs in levels of indirection from 'string_vec_t'
1>error C2530: 'r': references must be initialized
Комментарии:
1. Почему бы вам не написать функцию?
2. Вызывая
do_this(amp;r);
вы передаетеstring_vec_t*
, а неstring_vec_tamp;
3.
do_this(r);
для вызова эталонной версии. Удалите оператор addressof.4. Прошу прощения, пример неверен. «struct do_this: do_what { public: string_vec_t *r; do_this(string_vec_t *r): r(r) { } переопределение действия виртуальной пустоты() { } }; «
5. @BenS Если это неправильно, пожалуйста, отредактируйте вопрос, а не просто оставьте комментарий. Вам также следует уточнить, что именно вы подразумеваете под «по какой-то причине это не работает».
Ответ №1:
my_visit_items(amp;r /*, 0 */);
это объявление my_visit_items
ссылки r
, точно так же, как my_visit_items amp;r;
было бы. Попробуйте вместо этого равномерную инициализацию. Вы также должны стараться избегать передачи указателей на строки и векторы по кругу. Код, который вы показали, прекрасно работал бы без указателей:
#include <iostream>
#include <vector>
#include <string>
typedef std::vector<std::string> string_vec_t;
//-------------------------------------------------------------------------
struct visit_items {
virtual void action(const std::stringamp; s) = 0;
virtual ~visit_items() = default;
};
void items_visitor(visit_itemsamp; v) {
string_vec_t l = {"1", "2", "3", "4"};
for(autoamp; s : l) v.action(s);
}
struct my_visit_items : visit_items {
string_vec_tamp; r;
my_visit_items(string_vec_tamp; r) :
visit_items{},
r(r)
{
items_visitor(*this);
}
virtual void action(const std::stringamp; s) override {
r.push_back(s);
std::cout << "Visited: " << s << "n";
}
};
//-------------------------------------------------------------------------
int main() {
string_vec_t r;
r.push_back("1");
my_visit_items{r}; // { } instead of ( )
return 1;
}
Комментарии:
1. Спасибо тебе, Тед. В этом и заключалась проблема!
Ответ №2:
Когда вы хотите передать ссылку, вам нужно вызвать do_this(r);
С помощью calling do_this(amp;r)
, на который вы передаете указатель r
.
Далее вы можете вызвать конструктор (теоретически) напрямую с помощью do_this::do_this(r);
Но почему бы не использовать функцию, когда вы хотите иметь функцию? Не каждый компилятор позволяет это без явной настройки некоторых параметров компилятора (например, gcc требует -fpersmissive).
Если причина в том, что вы хотите реализовать свою функцию только один раз, то вызовите функцию из конструктора.
Если вы хотите иметь функцию, которая инкапсулируется в class, не требуя атрибутов класса, вы также можете использовать static
функцию-член класса.
Комментарии:
1. Спасибо за ваш ответ, у меня был неправильный фрагмент кода, и я соответствующим образом его обновил. Пожалуйста, удалите свой ответ и мои комментарии, чтобы лучше отразить эту тему.
Ответ №3:
Не связано с ошибками.
В моем Linux g -v7:
Если вы включите достаточное количество флагов компилятора, вы можете обнаружить, что компилятор предупреждает об этой структуре:
struct visit_items
{
virtual void action(std::string *s) = 0;
};
с помощью
// warning: ‘struct visit_items’ has virtual functions and
// accessible non-virtual destructor [-Wnon-virtual-dtor]
Примечание: Это предупреждение вызывает 2 другие проблемы (где используется класс).
Все это проясняется, когда вы предоставляете виртуальный dtor по умолчанию
struct visit_items
{
virtual ~visit_items() = default;
virtual void action(std::string *s) = 0;
};