c++ - Friend member function definition conflicts with in-class initializer -
i reading c++ primer , trapped same code in question (with little difference), question different. know there lot of similar questions, after searching around, seems no answer answer question.
at beginning, code worked fine when didn't add friend member function.
/* first class */ class screen { public: using pos = std::string::size_type; using content_type = char; screen() = default; screen(pos ht, pos wd, content_type c) : height(ht), width(wd), contents(ht * wd, c) {} // other inline functions omited. private: pos width = 0; pos height = 0; std::string contents; }; /* second class */ class window_mgr { public: using screen_index = std::vector<screen>::size_type; private: std::vector<screen> screens{screen(24, 80, ' ')}; // use `screen` ctor };
then, want add friend member function clear
. wrote 2 versions of code according code near page 281 in book. first version uses in-class initializer initialize vector
data member of window_mgr
, while second version uses constructor initializer list.
the first version (error) book wrote:
making member function friend requires careful structuring of our programs accommodate interdependencies among declarations , definitions. in example, must order our program follows:
- first, define
window_mgr
class, declares, cannot defineclear
.screen
must declared beforeclear
can use members ofscreen
.- next, define class
screen
, including friend declarationclear
.- finally, define
clear
, can refer members inscreen
.
/* part 1, window_mgr.h */ class screen; class window_mgr { public: using screen_index = std::vector<screen>::size_type; void clear(screen_index); private: std::vector<screen> screens{screen(24, 80, ' ')}; // error: no ctor `screen` }; /* part 2, screen.h */ class screen { friend void window_mgr::clear(screen_index); public: using pos = std::string::size_type; using content_type = char; screen() = default; screen(pos ht, pos wd, content_type c) : height(ht), width(wd), contents(ht * wd, c) {} // other inline functions omited. private: pos width = 0; pos height = 0; std::string contents; }; /* part 3, window_mgr.cpp */ void window_mgr::clear(screen_index i) { screen &s = screens[i]; s.contents = std::string(s.height * s.width, ' '); }
the second version (no error), inspired this answer:
/* part 1, window_mgr.h */ class screen; class window_mgr { public: using screen_index = std::vector<screen>::size_type; void clear(screen_index); window_mgr(); // add ctor declaration private: std::vector<screen> screens; // remove in-class initializer }; /* part 2, screen.h */ class screen { friend void window_mgr::clear(screen_index); public: using pos = std::string::size_type; using content_type = char; screen() = default; screen(pos ht, pos wd, content_type c) : height(ht), width(wd), contents(ht * wd, c) {} // other inline functions omited. private: pos width = 0; pos height = 0; std::string contents; }; /* part 3, window_mgr.cpp */ window_mgr::window_mgr() : screens{screen(24, 80, ' ')} {} // add ctor definition // because `screen` complete type, can use ctor void window_mgr::clear(screen_index i) { screen &s = screens[i]; s.contents = std::string(s.height * s.width, ' '); }
note put 3 parts of code in single file convenience, can split 3 different files proper include guards , include header files.
i understand forward declaration , include guards, i'm not asking them, here questions.
is constructor defined outside class
window_mgr
the way initialize data memberscreens
if want use classscreen
directly (not pointer or reference)?i think in-class initializer cannot used in first version because
screen
incomplete type when ctor called.why incomplete type (
screen
) can used parametervector
template?
possible similar questions:
- member function friend
- friend class or friend member function - forward declaration , header inclusion
- why aren't include guards preventing recursive inclusion , multiple symbol definitions?
i trying seems little bit verbose, anyway reading , helping :)
Comments
Post a Comment