| Home | Forums | Reviews | Guides | Newsgroups | Register | Search |
![]() |
| Thread Tools |
| Fabrizio J Bonsignore |
|
|
|
| |
|
Johannes Schaub (litb)
Guest
Posts: n/a
|
Fabrizio J Bonsignore wrote:
> What is the point of OOP and C++, anyway? I want to write ... AO > Function(); ... AO x = Function(); I want some NEW x object of type AO > in its relevant scope to CATCH the AO object returned from function > Function(); copy it and become IT. I do NOT want to have a previous AO > object initialized in default values, AO x; THEN an assignment > operator called on it with Function(); [like in x.this- Don't feed the troll... |
|
|
|
|
|||
|
|||
| Johannes Schaub (litb) |
|
|
|
| |
|
LR
Guest
Posts: n/a
|
Fabrizio J Bonsignore wrote:
> On Sep 17, 3:12 pm, Öö Tiib <oot...@hot.ee> wrote: >> If you did not declare copy constructor and assignment operator then >> compiler produces these for you (expect for cases the class was made >> not copyable). That has been so as long i remember in C++ so i do not >> get what you complain there. > > Indeed, it works automatically and will generate errors if you are > using pointers and managing your own memory. I thought the default copy ctor in this case would generate a shallow copy of the argument. > The AO has also been > normal C++ as long as I remember but now it is not working well. The > error message says: > > [line] no match for 'operator=' in 'f = BO::Retit()()' > [line] candidates are AO& operator=(AO&); > > !!! Precisely! What happens if you change that to AO &operator=(const AO &); > > The other error is similar: > > [line] no matching function for call to `AO::AO(AO)' > [line] candidates are: AO::AO(AO&) > [line] AO::AO() > > !!! Which is nonsense! These look like they may be compiler bugs, or else you may be compiling something different than what you posted. > > It SEEMS to work with AO:: (const AO &) in BOTH copy constructor and > assignment operators, the compiler accepts it (compile time), but > const here is almost optional and has been so since ever. Strictly > speaking it is not the same as AO::AO(AO const &x)... That seems pretty strict. I'm not sure how A0::AO(const AO &) and AO::AO(const AO &x) are different for purposes of this discussion. Can you please explain that? > and you would > even have to disambiguate to the extreme of AO::AO(const AO const & > const a)... and add all variants for BOTH assignment and copy > constructors! I'm not sure I follow that. I thought that AO(const AO &); and AO(AO const &); were equivalent. The compiler I use thinks so too. http://www.comeaucomputing.com/tryitout/ seems to indicate that this is the case as well. > In the program this problem arose it is NOT the case: I > need a SINGLETON, actually I need some UNIQUE reading to propagate > after initial construction wherever objects of primitive class AO take > it, UNTIL any of them is Closed(); which means in one scenario (maybe > at most) I have to discard the reading from the copied object... > violating the const. I'm not sure that I follow all of that, but it sounds like you want to be able to partially construct and object and perhaps not complete construction depending on some resource. Is that right? > It is NOT FUNNY that the suggestion was > AO::AO(const AO &) and not AO::AO(AO const &) or AO::AO(AO & const); > the latter variants did not compile! If you try them all together at once I don't think they will compile. And this Q(Q & const) {} got me a warning about an anachronism from my compiler. > This code here is trivial and > does nothing, but in real code I cannot truly know if I can honor ANY > constness in the argument object! But I'm confused as to why. When you call a ctor with a const reference, that object is, was, already constructed and it's not clear to me that you want to alter the already constructed argument. Or perhaps a slightly different design is what's needed since I think that a copy ctor that alters the argument tends, not always, but tends, to violate the principle of least astonishment. IMO. Or do you want to call a ctor with an argument that is only partially constructed? I don't think that's really possible. I think it's very likely that I don't understand what you mean. Maybe a small real world example is called for? > Which means the risk of needing to > defining different signatures with almost identical code to handle all > possibilities! Compared to the use of const, the solution AO::AO(AO > *a); AO a(&Function()); (take address of some temporary), seems > preferable, but the problem is still the insistence of g++ 3.4.2 in > finding AO::AO(AO) (!) when later it would say it IS an illegal copy > constructor signature. Again, this seems very peculiar. Also, from reading here http://gcc.gnu.org/ it seems that gcc 4.5.1 has been released. I think you've implied that gcc 3.4.2 is not the compiler that you've been using with this code. Is using this compiler a recent change? Do you get these errors when you compile the code that you posted here? LR |
|
|
|
|
|||
|
|||
| LR |
|
Fabrizio J Bonsignore
Guest
Posts: n/a
|
Oops!
On Sep 17, 5:38*pm, LR <lr...@superlink.net> wrote: > Fabrizio J Bonsignore wrote: > > On Sep 17, 3:12 pm, Öö Tiib <oot...@hot.ee> wrote: > >> If you did not declare copy constructor and assignment operator then > >> compiler produces these for you (expect for cases the class was made > >> not copyable). That has been so as long i remember in C++ so i do not > >> get what you complain there. > > > Indeed, it works automatically and will generate errors if you are > > using pointers and managing your own memory. > > I thought the default copy ctor in this case would generate a shallow > copy of the argument. Indeed a shallow bitwise copy of member object data, so if any of them is a pointer (heap memory), you end up with two copies of the same pointer value! Which means you cannot simply delete the pointer in the destructor because you would delete it twice so that particular object cannot manage that pointer s memory! The common case is char *texts, each instance has its own text (if necessary), or can choose to make it 0, which makes sense if the text is user initialized! For example, you copy a bitmap object (bitwise data), then wait for the user to give it a name or it ends up recorded as noname [if ((char *)text == 0...)] Shallow copy constructors are unacceptable here. > > The AO has also been > > normal C++ as long as I remember but now it is not working well. The > > error message says: > > > [line] no match for 'operator=' in 'f = BO::Retit()()' > > [line] candidates are AO& operator=(AO&); > > > !!! Precisely! > > What happens if you change that to > > AO &operator=(const AO &); > That s the solution you provided! And it worked as long as BOTH assignment operator and copy constructor are signed as (const AO &); > > > The other error is similar: > > > [line] no matching function for call to `AO::AO(AO)' > > [line] candidates are: AO::AO(AO&) > > [line] * * * * * * * * AO::AO() > > > !!! Which is nonsense! > > These look like they may be compiler bugs, or else you may be compiling > something different than what you posted. > It is the case, seems to be a bug in the compiler but it MAY be a combination of compiler flags that has to be defined to avoid that error. In any case it is in the compiler where you do NOT expect nor can accept bugs at all... or your code becomes undefined! > > > It SEEMS to work with AO:: (const AO &) in BOTH copy constructor and > > assignment operators, the compiler accepts it (compile time), but > > const here is almost optional and has been so since ever. Strictly > > speaking it is not the same as AO::AO(AO const &x)... > > That seems pretty strict. I'm not sure how > > A0::AO(const AO &) > and > AO::AO(const AO &x) > > are different for purposes of this discussion. Can you please explain that? > Should not matter, but you can ask for a warning on the lines of: unused function argument or something similar. I ve always considered signature argument names as documentation and definition argument names as minimum name variables, but since the language can accept function calls in the SIGNATURE of a member function (even anonymous classes lately...), I always define them even if unneeded for the method (like the int in post/pre fix operator++). > > *and you would > > even have to disambiguate to the extreme of AO::AO(const AO const & > > const a)... and add all variants for BOTH assignment and copy > > constructors! > > I'm not sure I follow that. *I thought that > You can consider the REFERENCE as const or the OBJECT REFERRED TO as const or the VARIABLE NAME as const... or all three... but I omit const as far as possible. In worst cases const propagates to all methods of a class! So you end up having version void F(AO); void F(const AO); etc. duplicated, but doing exactly the same, to the extent the const_cast operator became necessary to take away/add const in hard cases. I never use it, so I am not sure of all the consequences and differences between those signatures, though the difference is real for the compiler, or should be. > AO(const AO &); and AO(AO const &); were equivalent. The compiler I use > thinks so too.http://www.comeaucomputing.com/tryitout/seems to > indicate that this is the case as well. > Nope, it may be but you can read both version as different referents... const AO says that the object cannot stop being an AO! If that is the case (more testing...), how can you pass it as argument to a BASE CLASS copy constructor? Strictly speaking you would have to cast down to base class and even take away the const first, cast, then add the const again! But too much expliciting of polymorphism actually DESTROYS IT, you want your polymorphism to be TRANSPARENT for the user because it hides complexity. > > In the program this problem arose it is NOT the case: I > > need a SINGLETON, actually I need some UNIQUE reading to propagate > > after initial construction wherever objects of primitive class AO take > > it, UNTIL any of them is Closed(); which means in one scenario (maybe > > at most) I have to discard the reading from the copied object... > > violating the const. > > I'm not sure that I follow all of that, but it sounds like you want to > be able to partially construct and object and perhaps not complete > construction depending on some resource. Is that right? Specifically I wanted to erase the reading from the copied object and _move_it_ into the new, copied-to object, so the original object would not invoke Close() in the destructor after finding an empty reading. This assumes new objects s lifespans are longer than the sources and get destructed later, which is a very good assumption IF you copy around objects by value! The original gets destroyed in the originating function, the function that catches it now has the rading and MAY be the function that ultimately can call Close() or destroy the object to get a final legitimate reading. > > It is NOT FUNNY that the suggestion was > > AO::AO(const AO &) and not AO::AO(AO const &) or AO::AO(AO & const); > > the latter variants did not compile! > > If you try them all together at once I don't think they will compile. > And this Q(Q & const) {} got me a warning about an anachronism from my > compiler. }-) That s the point! It takes time to test... but here the point is other similar posts all suggest (AO const &) [const reference to object of type AO] and not the _working_ const object of type AO taken by reference. I am not sure, but that anachronism may mean you can only call some methods on the [ommitted] variable and not others depending on the placement of their constness const int F(); vs int F() const; Which IS one the reason why I am perplexed that the compiler does not let me decide if I change the argument object in a constructor or not. > > This code here is trivial and > > does nothing, but in real code I cannot truly know if I can honor ANY > > constness in the argument object! > > But I'm confused as to why. *When you call a ctor with a const > reference, that object is, was, already constructed and it's not clear > to me that you want to alter the already constructed argument. *Or > perhaps a slightly different design is what's needed since I think that > a copy ctor that alters the argument tends, not always, but tends, to > violate the principle of least astonishment. IMO. > I am astonished. Reference counting seems to be the typical case where constness can be broken by necessity, but there are other schemes. const means that you agree NOT to modify the argument, which is why you have to define const methods if you want to call methods at all! It makes for very inefficient programming... The bad C assumption is that all you can and want to do with the argument is to copy data, but it IS the natural place to perform initializations, management, profiling, synchronizations... because the argument is an OBJECT and includes methods. O CloneX() seems to be a valid method to define and call in a copy constructor method for members of type O. > Or do you want to call a ctor with an argument that is only partially > constructed? *I don't think that's really possible. I think it's very > likely that I don't understand what you mean. Maybe a small real world > example is called for? But that seems to be what the compiler is doing! It SEEMS to be creating a temporary with the default constructor, then complaining that it cannot assign it (because it is partially constructed)! The error Retut()() implies (Retut()=AO)() === default constructor, then gets lost because it cannot call in addition AO(AO...)! > > Which means the risk of needing to > > defining different signatures with almost identical code to handle all > > possibilities! Compared to the use of const, the solution AO::AO(AO > > *a); AO a(&Function()); (take address of some temporary), seems > > preferable, but the problem is still the insistence of g++ 3.4.2 in > > finding AO::AO(AO) (!) when later it would say it IS an illegal copy > > constructor signature. > > Again, this seems very peculiar. Also, from reading herehttp://gcc.gnu.org/it seems that gcc 4.5.1 has been released. > > I think you've implied that gcc 3.4.2 is not the compiler that you've > been using with this code. Is using this compiler a recent change? > > Do you get these errors when you compile the code that you posted here? > .... gcc 4.5.1 seems to keep adding and adding to the language... and to the list of BUGS. 4.5.1 means to go through a new installation but I got my version bundled. I was reading the known bugs and it seems to keep changing things to new features I do not plan to use which besides are still buggy! My point is that the code I posted here [AO and BO] is such typical and basic C++ it has to compile. The version I ve been using exclusively is 3.4.2 I do not want to change it... unless it has a real crucial error. Which is what I want to determine. Danilo J Bonsignore |
|
|
|
|
|||
|
|||
| Fabrizio J Bonsignore |
|
Fabrizio J Bonsignore
Guest
Posts: n/a
|
On Sep 16, 10:04*pm, Fabrizio J Bonsignore <synto...@gmail.com> wrote:
> Like in AO::AO((AO &)(AO&)Function()); so both (AO &) terms cancel each other out AS IF this was a mathematical algebra... This seems to be an undocumented or misclassified bug in the compiler frontend. It seems to be comparing directly and literally the signature of the copy constructor, taking a reference, and the signature of any function returning the same object type by value. Since the function does not return a reference... the constructor does not take the value by reference! The SEMANTIC is DIFFERENT, but in the code the comparison seems to be SYNTACTIC and literal! Strictly speaking should be a less or greater equal than comparison, not an equal to comparison. The programmer is taking the return type of a function, then matching literally against the known signatures for constructors in the class (at least forward defined as the function is in another object). Since literally the AO in AO Function(); is NOT identical to AO& in the constructor... it asks for an illegal AO::AO(AO) constructor! But if the function is defined as AO& Function(); THEN the literal identical match succeeds! The programmer would have to make something like if (AO == AO || AO == AO&) accept(); In actual code the situation may be hidden by the temporary. The error message no match ... ::Retut()() implies a temporary spureous call to the default constructor! Of course I have no indication this problem is not carried into next versions unless the bug is documented, but I still have doubts if it is a spureous bug that will go away by writing more code or a hidden bug that will explode at the least expected moment (say, in some multithreading or window switching contexts)! So far it shows up in this project but not in another project. The other project does not exhaust copying possibilities while here I am using all possibilities. It shows up for an empty class too built ex professo but goes away with both workarounds. Danilo J Bonsignore |
|
|
|
|
|||
|
|||
| Fabrizio J Bonsignore |
|
LR
Guest
Posts: n/a
|
Fabrizio J Bonsignore wrote:
> Oops! > > On Sep 17, 5:38 pm, LR <lr...@superlink.net> wrote: >> Fabrizio J Bonsignore wrote: >>> On Sep 17, 3:12 pm, Öö Tiib <oot...@hot.ee> wrote: >>>> If you did not declare copy constructor and assignment operator then >>>> compiler produces these for you (expect for cases the class was made >>>> not copyable). That has been so as long i remember in C++ so i do not >>>> get what you complain there. >> >>> Indeed, it works automatically and will generate errors if you are >>> using pointers and managing your own memory. >> >> I thought the default copy ctor in this case would generate a shallow >> copy of the argument. > > Indeed a shallow bitwise copy of member object data, so if any of them > is a pointer (heap memory), you end up with two copies of the same > pointer value! Which means you cannot simply delete the pointer in the > destructor because you would delete it twice so that particular object > cannot manage that pointer s memory! The common case is char *texts, > each instance has its own text (if necessary), or can choose to make > it 0, which makes sense if the text is user initialized! For example, > you copy a bitmap object (bitwise data), then wait for the user to > give it a name or it ends up recorded as noname [if ((char *)text == > 0...)] Shallow copy constructors are unacceptable here. > >>> The AO has also been >>> normal C++ as long as I remember but now it is not working well. The >>> error message says: >> >>> [line] no match for 'operator=' in 'f = BO::Retit()()' >>> [line] candidates are AO& operator=(AO&); >> >>> !!! Precisely! >> >> What happens if you change that to >> >> AO &operator=(const AO &); >> > That s the solution you provided! And it worked as long as BOTH > assignment operator and copy constructor are signed as (const AO &); Maybe that's the fix you're looking for then. I'm wondering if this is related http://gcc.gnu.org/bugzilla/show_bug.cgi?id=16889 Followed link from http://gcc.gnu.org/gcc-3.4/changes.html#3.4.2 Followed link from http://gcc.gnu.org/gcc-3.4/ > >> >>> The other error is similar: >> >>> [line] no matching function for call to `AO::AO(AO)' >>> [line] candidates are: AO::AO(AO&) >>> [line] AO::AO() >> >>> !!! Which is nonsense! >> >> These look like they may be compiler bugs, or else you may be compiling >> something different than what you posted. >> > It is the case, seems to be a bug in the compiler but it MAY be a > combination of compiler flags that has to be defined to avoid that > error. In any case it is in the compiler where you do NOT expect nor > can accept bugs at all... or your code becomes undefined! gcc 3.4.2 was released in 2004. Compilers have bugs. You can find the list for 3.4.2 at one of the links above. Although, this seems like a fairly fundamental thing. [snip] > You can consider the REFERENCE as const or the OBJECT REFERRED TO as > const or the VARIABLE NAME as const... or all three... I don't follow that as all. I think that references are const. You can't change them once they're initialized. An object that is referenced can be const. The variable name? You've lost me there. I don't know what that means. > but I omit > const as far as possible. In worst cases const propagates to all > methods of a class! So you end up having version void F(AO); void > F(const AO); etc. duplicated, but doing exactly the same, No. They don't do the same thing, and this can be very useful. Personally I think it's much easier to write and debug code where as much as possible is const. But maybe that's just me. >> AO(const AO &); and AO(AO const &); were equivalent. The compiler I use >> thinks so too.http://www.comeaucomputing.com/tryitout/seems to >> indicate that this is the case as well. >> > Nope, it may be but you can read both version as different > referents... const AO says that the object cannot stop being an AO! If > that is the case (more testing...), how can you pass it as argument to > a BASE CLASS copy constructor? I'm not sure I understand. Do you mean like this: class Base { .... public: Base(const Base &b) {} }; class Derived : public Base { ..... public: Derived(const Derived &d) : Base(d) {} }; I don't see the problem. > Strictly speaking you would have to > cast down to base class and even take away the const first, cast, then > add the const again! But too much expliciting of polymorphism actually > DESTROYS IT, you want your polymorphism to be TRANSPARENT for the user > because it hides complexity. I'm sorry, but I still don't see the problem. [snip] > Specifically I wanted to erase the reading I'm not sure what you mean by "erase the reading". > from the copied object and > _move_it_ into the new, copied-to object, so the original object would > not invoke Close() in the destructor after finding an empty reading. An empty reading? Are you reading a file to construct your object? > This assumes new objects s lifespans are longer than the sources and > get destructed later, which is a very good assumption IF you copy > around objects by value! The original gets destroyed in the > originating function, the function that catches it Are you throwing an exception? > now has the rading > and MAY be the function that ultimately can call Close() or destroy > the object to get a final legitimate reading. Sorry. I don't understand that. > >>> It is NOT FUNNY that the suggestion was >>> AO::AO(const AO &) and not AO::AO(AO const &) or AO::AO(AO & const); >>> the latter variants did not compile! >> >> If you try them all together at once I don't think they will compile. >> And this Q(Q & const) {} got me a warning about an anachronism from my >> compiler. > > }-) That s the point! It takes time to test... but here the point is > other similar posts all suggest (AO const &) [const reference to > object of type AO] and not the _working_ const object of type AO taken > by reference. I am not sure, but that anachronism may mean you can > only call some methods on the [ommitted] variable and not others > depending on the placement of their constness const int F(); vs int > F() const; Assuming that both of these are class members. Where const int f(); is a function that returns a const int. then SomeClass obj; // can't be const, calling a non const method. int t = obj.f(); // obj might change or const int t = obj.f(); // obj might change Where int f() const; is a function returns an int that will not change the object f() is called with. then SomeClass obj; // could be const if I want. int t = obj.f(); // obj won't be changed or const int t = obj.f(); // obj won't be changed >> But I'm confused as to why. When you call a ctor with a const >> reference, that object is, was, already constructed and it's not clear >> to me that you want to alter the already constructed argument. Or >> perhaps a slightly different design is what's needed since I think that >> a copy ctor that alters the argument tends, not always, but tends, to >> violate the principle of least astonishment. IMO. >> > I am astonished. Reference counting seems to be the typical case where > constness can be broken by necessity, but there are other schemes. > const means that you agree NOT to modify the argument, which is why > you have to define const methods if you want to call methods at all! > It makes for very inefficient programming... I find that const makes me more efficient, not less. > The bad C assumption is > that all you can and want to do with the argument is to copy data, but > it IS the natural place to perform initializations, management, > profiling, synchronizations... For the object that is being constructed. > because the argument is an OBJECT and > includes methods. O CloneX() seems to be a valid method to define and > call in a copy constructor method for members of type O. Now you've lost me again. But in general, I'd say this depends on what you want to accomplish. IME, keeping the args to assignment operators and copy ctors, in fact almost all arguments const, saves me time later. > ... gcc 4.5.1 seems to keep adding and adding to the language... and > to the list of BUGS. 4.5.1 means to go through a new installation but > I got my version bundled. I was reading the known bugs and it seems to > keep changing things to new features I do not plan to use which > besides are still buggy! In my sad experience all compilers have bugs. > My point is that the code I posted here [AO > and BO] is such typical and basic C++ it has to compile. The version I > ve been using exclusively is 3.4.2 I do not want to change it... > unless it has a real crucial error. Which is what I want to determine. According to the faq http://www.parashift.com/c++-faq-lit...t.html#faq-5.9 you might want to post in gnu.g++.help to get compiler specific help. LR |
|
|
|
|
|||
|
|||
| LR |
|
Kai-Uwe Bux
Guest
Posts: n/a
|
Fabrizio J Bonsignore wrote:
> On Sep 17, 3:12 pm, Öö Tiib <oot...@hot.ee> wrote: >> If you did not declare copy constructor and assignment operator then >> compiler produces these for you (expect for cases the class was made >> not copyable). That has been so as long i remember in C++ so i do not >> get what you complain there. > > Indeed, it works automatically and will generate errors if you are > using pointers and managing your own memory. The AO has also been > normal C++ as long as I remember but now it is not working well. The > error message says: > > [line] no match for 'operator=' in 'f = BO::Retit()()' > [line] candidates are AO& operator=(AO&); > > !!! Precisely! > > The other error is similar: > > [line] no matching function for call to `AO::AO(AO)' > [line] candidates are: AO::AO(AO&) > [line] AO::AO() > > !!! Which is nonsense! > > It SEEMS to work with AO:: (const AO &) in BOTH copy constructor and > assignment operators, the compiler accepts it (compile time), The difference lies in clause [8.5.3/5]. Temporaries cannot be used to initialize references _unless_ they are references to const. Hence, a copy constructor or assignment operator whose argument is a non-const reference cannot be used with a temporary. C++0x will introduce rvalue reverences which might help with your problem should you really need non-const arguments to copy constructor and assignment operator. > but const here is almost optional and has been so since ever. [...] The const is not and was not optional: clause [8.5.3/5] has been in the standard from the start (199 Best Kai-Uwe Bux |
|
|
|
|
|||
|
|||
| Kai-Uwe Bux |
|
James Kanze
Guest
Posts: n/a
|
On Sep 17, 8:57 pm, Fabrizio J Bonsignore <synto...@gmail.com> wrote:
> On Sep 17, 3:12 pm, Öö Tiib <oot...@hot.ee> wrote: > > If you did not declare copy constructor and assignment > > operator then compiler produces these for you (expect for > > cases the class was made not copyable). That has been so as > > long i remember in C++ so i do not get what you complain > > there. > Indeed, it works automatically and will generate errors if you > are using pointers and managing your own memory. The AO has > also been normal C++ as long as I remember but now it is not > working well. The error message says: > [line] no match for 'operator=' in 'f = BO::Retit()()' > [line] candidates are AO& operator=(AO&); > !!! Precisely! > The other error is similar: > [line] no matching function for call to `AO::AO(AO)' > [line] candidates are: AO::AO(AO&) > [line] AO::AO() > !!! Which is nonsense! It would help if you'd give more code, instead of just ranting. But even from just the error messages, I'd guess you're missing a const in the declarations of the copy constructor and the assignment operator. > It SEEMS to work with AO:: (const AO &) in BOTH copy > constructor and assignment operators, the compiler accepts it > (compile time), but const here is almost optional and has been > so since ever. The const in these is *not* optional, and hasn't been since CFront 2.1 (1989, or some time around then). You cannot initialize a non-const reference with a temporary (and the results of a function call is a temporary). Some compilers have been a bit slow about enforcing this, but that's not a general rule; it was enforced by compilers I was using in the early 1990's. > Strictly speaking it is not the same as AO::AO(AO const &x)... > and you would even have to disambiguate to the extreme of > AO::AO(const AO const & const a)... and add all variants for > BOTH assignment and copy constructors! I'd suggest you learn how const works in C++. Something like AO::AO(const AO const & const a) is illegal, for two reasons. And you can bind a non-const object to a reference to const; usually, the copy constructor and the assignment operator take references to const, and are not overloaded for non-const. > In the program this problem arose it is NOT the case: I > need a SINGLETON, actually I need some UNIQUE reading to propagate > after initial construction wherever objects of primitive class AO take > it, UNTIL any of them is Closed(); which means in one scenario (maybe > at most) I have to discard the reading from the copied object... > violating the const. It is NOT FUNNY that the suggestion was > AO::AO(const AO &) and not AO::AO(AO const &) or AO::AO(AO & const); I'm not sure what you're talking about. AO::AO(const AO&) and AO::AO(AO const&) are exactly the same thing (and the second is the prefered way of writing it today), and AO::AO(AO& const) is illegal (since a reference is always const, and can't be declared const). > the latter variants did not compile! The last shouldn't. The other two should (and do with every compiler I've ever used). > This code here is trivial and does nothing, but in real code I > cannot truly know if I can honor ANY constness in the argument > object! That's an unusual case. It's likely a design error (since you'd be modifying a temporary, which will be immediately destroyed), but there are exceptions, most of which can be fairly easily handled by an appropriate use of mutable. > Which means the risk of needing to defining different > signatures with almost identical code to handle all > possibilities! I have yet to see any case where it made sense to overload the copy constructor on const-ness. > Compared to the use of const, the solution AO::AO(AO > *a); AO a(&Function()); (take address of some temporary), seems > preferable, You can't take the address of a temporary (unless you provide a user defined operator&). It's not allowed by the language. > but the problem is still the insistence of g++ 3.4.2 in > finding AO::AO(AO) (!) when later it would say it IS an > illegal copy constructor signature. Different errors are detected at different phases of compilation. A constructor AO::AO(AO) is illegal---it would be useless if it weren't, since it would result in infinite recursion if it were ever called. -- James Kanze |
|
|
|
|
|||
|
|||
| James Kanze |
|
Fabrizio J Bonsignore
Guest
Posts: n/a
|
On Sep 18, 7:28*am, James Kanze <james.ka...@gmail.com> wrote:
> On Sep 17, 8:57 pm, Fabrizio J Bonsignore <synto...@gmail.com> wrote: > > The const in these is *not* optional, and hasn't been since > CFront 2.1 (1989, or some time around then). *You cannot > initialize a non-const reference with a temporary (and the > results of a function call is a temporary). > > Some compilers have been a bit slow about enforcing this, but > that's not a general rule; it was enforced by compilers I was > using in the early 1990's. I have another project open, the compiler accepts a copy constructor and finds it without const and without errors, compile time or run time. This problem was surprising! That other class does derive from a Windows struct and has conversion semantics to it, it defines both assignment operator= and copy constructor without const... and the compiler accepts it. I ll have to review that code to see which one of my cases (in a previous post) I did NOT use in that project that the compiler did not fail. I am quite liberal in the use of that beefed up struct as it is now a very basic variable/object in that system and there has been no such weird error messages. But this may be the case because it actually IS-A Windows defined struct, so the actual Windows definition may be affecting compilation. OF COURSE this means to me more testing... > > > Compared to the use of const, the solution AO::AO(AO > > *a); AO a(&Function()); (take address of some temporary), seems > > preferable, Oh, but it DID accept it! There s where I got stopped. Actually it makes sense: the temporary, or anonymous variable, MUST keep existing til the end of the current out-of-returning-function statement or the data gets completely lost! And there is no reason why the memory address should become invalid AFTER entering the same statement, which happens to be... a copy constructor defined with a pointer argument! At what point should the function-returned byvalue copy be destroyed? The problem is still that this idiom seems to imply there was in implicit copy constructor called in between, from the in-function built object to the copy out-of-return-function that reaches the next, copy constructor method and ends as argument to the next method code. If the returned object, in the stack frame, is the same from WITHIN the previous call and INTO the next call, no problema! The address is valid. In effect the copy constructor gets the right data, though something tells me that entering the new, non inlined, copy- constructor-from-pointer, the stack frame should have been modified, should contain ONLY this and address-of-object and... oops! But the actual contents of the previous frame are NOT defined in the stack itself! Unless there is a system (C++) call to **garbage collecting** in between frame changes the data should STILL be... in the memory area of the previous frame in the stack! This seems to be the actual event, but no guarantee it will ALWAYS happen the same for all classes, all returning functions and all copy constructors from temporary pointer! Or is there? If the stack frame is actually a stack and contains frames objects, when will that memory be overwritten? I do not want to go so deeply into C++ compiling workings now! the idiom that worked let me write something like: AO a( &(object.method(argument)).functionReturningAO( ) ); and it passes compilation. Should I leave it like that? > You can't take the address of a temporary (unless you provide a > user defined operator&). *It's not allowed by the language. Nope, no operator& defined here... though there IS a pointer to object member object conversion operator defined...[ operator STRUCT*() {return &member;} ] which should NOT interfere anyway, as there is no constructor AO::AO(STRUCT...) whatsoever to ambiguate calls for the compiler, which incidentally has always been kind of a nuisance in the language to make primitive type like classes... This means more testing... but the AO example is simpler and does have the same error message. > > Different errors are detected at different phases of > compilation. *A constructor AO::AO(AO) is illegal---it would be > useless if it weren't, since it would result in infinite > recursion if it were ever called. That seems to be a REAL bug in the compiler: the problem is something different, it should mention the lack of const as a warning (AT MOST, I insist current practice is to make const optional), and the form of such error message is so easily detectable that it can be substituted by anything else in the next error reporting pass, if not completely changed. Danilo J Bonsignore |
|
|
|
|
|||
|
|||
| Fabrizio J Bonsignore |
|
Fabrizio J Bonsignore
Guest
Posts: n/a
|
On Sep 18, 2:39*am, Kai-Uwe Bux <jkherci...@gmx.net> wrote:
> Fabrizio J Bonsignore wrote: > > The other error is similar: > > > [line] no matching function for call to `AO::AO(AO)' > > [line] candidates are: AO::AO(AO&) > > [line] * * * * * * * * AO::AO() > > > !!! Which is nonsense! > > The const is not and was not optional: clause [8.5.3/5] has been in the > standard from the start (199 > It IS optional even if included in the _description_ of the language. But I ve been programming C++ since 1992! It was already a well established language and superior to C, Pascal, Basic, macro languages... Adding const was a nuisance then and besides the way C++ is layered, and given access specifiers, well programmed classes will never have side effect troubles from non sprinkling const liberally! I insist such is the case that the const_cast<> operator had to be added. In any case, standards are complex documents and their link to actual working and functioning practice is similar to the relationship between Life and Movies or Literature... Too late... but maybe it would be worth the while to first describe WORKING languages as they ARE, then comparatively design a future fantasy, because it seems that industry standard practice is stronger than **standard documents**. Danilo J Bonsignore |
|
|
|
|
|||
|
|||
| Fabrizio J Bonsignore |
|
|
|
| |
![]() |
| Thread Tools | |
|
|
Similar Threads
|
||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| Assignment operator self-assignment check | Chris | C++ | 34 | 09-26-2006 04:26 AM |
| Augument assignment versus regular assignment | nagy | Python | 36 | 07-20-2006 07:24 PM |
| Question about interference and Wireless Channel Assignment | HOESan | Wireless Networking | 4 | 09-04-2004 08:36 PM |
| Comparison of Bit Vectors in a Conditional Signal Assignment Statement | Anand P Paralkar | VHDL | 2 | 08-04-2003 08:40 PM |
| Help: conditional attribute assignment | itsme | VHDL | 1 | 07-23-2003 03:26 PM |
Powered by vBulletin®. Copyright ©2000 - 2013, vBulletin Solutions, Inc..
SEO by vBSEO ©2010, Crawlability, Inc. |




