Почему не вызывается конструктор копирования при инициализации переменной другим объектом?
Понимаю что исходный код достаточно большой, но все же, надеюсь кто то да подскажет.
Пытаюсь разобраться с кодом из книги Lippman С++ Primer, конец 15 главы.
Возможно я что то неправильно понимаю, но почему в main
в строке:
Query query = Query("she") & Query("is");
копирующий конструктор Query вызывается всего 2 раза при вызове конструктора BinaryQuery
, когда происходит инициализация lhs
и rhs
, но не вызывается когда собственно инициализируется переменная query
в функции main
?
Собственно и не могу понять каким образом инициализируется эта переменная если не при помощи копирующего конструктора.
Как я понял, алгоритм выполнения следующий:
- Создается файловый поток
- Создается объект класса
TextQuery
- Вызывается конструктор
Query(string)
с аргументом"she"
(внутри вызываетсяWordQuery(string)
) - Вызывается конструктор
Query(string)
с аргументом"is"
(внутри вызываетсяWordQuery(string)
) - Вызывается оператор
&
с двумя аргументами - Вызывается конструктор
AndQuery
в который передаются оба операнда - Вызывается конструктор
BinaryQuery
в котором происходит инициализация lhs и rhs с помощью копирующего конструкторQuery
- Далее вызывается конструктор
Query
с параметромshared_ptr
, после чего q ссылается на AndQuery объект - И вот тут по моему должен вызываться копирующий конструктор
Query
чтобы произошла инициализация переменнойquery
в функцииmain
, но почему то этого не происходит...
Исходный код:
using namespace std;
class QueryResult
{
public:
using line_no = vector<string>::size_type;
QueryResult(string sw, shared_ptr<set<line_no>> ln, shared_ptr<vector<string>> ft) : sought_word(sw), lines_numbers(ln), file_text(ft) {}
auto begin() const { return lines_numbers->begin(); }
auto end() const { return lines_numbers->end(); }
auto get_file() const { return file_text; }
private:
string sought_word;
shared_ptr<set<line_no>> lines_numbers;
shared_ptr<vector<string>> file_text;
};
class TextQuery
{
public:
using line_no = vector<string>::size_type;
TextQuery(ifstream& is) : file_text(new vector<string>)
{
string line;
while (getline(is, line))
{
file_text->push_back(line);
istringstream line_stream(line);
string word;
while (line_stream >> word)
{
auto& lines_numbers = words_map[word];
if (!lines_numbers) lines_numbers.reset(new set<line_no>);
lines_numbers->insert(file_text->size() - 1);
}
}
}
QueryResult query(const string& sought_word) const
{
static shared_ptr<set<line_no>> no_data(new set<line_no>);
auto loc = words_map.find(sought_word);
if (loc == words_map.end()) return QueryResult(sought_word, no_data, file_text);
else return QueryResult(sought_word, loc->second, file_text);
}
private:
shared_ptr<vector<string>> file_text;
map<string, shared_ptr<set<line_no>>> words_map;
};
class QueryBase
{
friend class Query;
protected:
using line_no = TextQuery::line_no;
virtual ~QueryBase() = default;
private:
virtual QueryResult eval(const TextQuery&) const = 0;
virtual string rep() const = 0;
};
class Query
{
friend Query operator~(const Query&);
friend Query operator|(const Query&, const Query&);
friend Query operator&(const Query&, const Query&);
friend ostream& operator<<(ostream&, const Query&);
public:
Query(const string&);
Query(const Query& query)
{
cout << "Here..." << endl;
q = query.q;
}
QueryResult eval(const TextQuery& t) const { return q->eval(t); }
string rep() const { return q->rep(); }
private:
Query(shared_ptr<QueryBase> query) : q(query) {}
shared_ptr<QueryBase> q;
};
ostream& operator<<(ostream& os, const Query& query)
{
return os << query.rep();
}
class WordQuery : public QueryBase
{
friend class Query;
private:
WordQuery(const string& s) : query_word(s) {}
QueryResult eval(const TextQuery& t) const { return t.query(query_word); }
string rep() const { return query_word; }
string query_word;
};
inline Query::Query(const string& s) : q(new WordQuery(s)) {}
class BinaryQuery : public QueryBase
{
protected:
BinaryQuery(const Query& l, const Query& r, string s) : lhs(l), rhs(r), op_sym(s) {}
string rep() const { return "(" + lhs.rep() + " " + op_sym + " " + rhs.rep() + ")"; }
Query lhs;
Query rhs;
string op_sym;
};
class AndQuery : public BinaryQuery
{
friend Query operator&(const Query&, const Query&);
AndQuery(const Query& left, const Query& right) : BinaryQuery(left, right, "&") {}
QueryResult eval(const TextQuery& text) const
{
auto left = lhs.eval(text);
auto right = rhs.eval(text);
auto ret_lines = make_shared<set<line_no>>();
set_intersection(left.begin(), left.end(), right.begin(), right.end(), inserter(*ret_lines, ret_lines->begin()));
return QueryResult(rep(), ret_lines, left.get_file());
}
};
inline Query operator&(const Query& lhs, const Query& rhs)
{
auto temp = shared_ptr<QueryBase>(new AndQuery(lhs, rhs));
return Query(temp);
}
int main()
{
ifstream file("./file.txt");
TextQuery text_query(file);
Query query = Query("she") & Query("is"); // ???????????????????????
print(cout, query.eval(text_query));
return 0;
}
Источник: Stack Overflow на русском