Tuesday, 15 May 2012

boost - C++ swap problem in inheritance scenario -


I want to add swap functionality to two existing C ++ classes. One class gets from the other. I want the examples of each class to be swapable with examples of only one class. To make this semi-concrete, say that I have the classes Fu and Bar are received from the bar fu. I define Fu :: Swap (Foo End) and Bar :: swap (bar end). Time :: Swap Delegate Fu :: Swap I want Foo :: Swap to work only on Fu instances and work Bar: swap only on bar instances: I can not understand the method of implementing this requirement.

Here's a sample of what is giving me trouble:

  Include # lt; Algorithm & gt; # Include & lt; Iostream & gt; Structure fu {int x; Foo (int x): x (x) {}; Virtual Zero Swap (Foo and others) {std :: cout & lt; & Lt; __PRETTY_FUNCTION__ & lt; & Lt; Std :: endl; Std :: swap (this->; x, other.x); }; }; Structure bar: Public fu {int y; Bar (int x, int y): fu (x), y (y) {}; Virtual Zero Swap (bar and others) {std :: cout & lt; & Lt; __PRETTY_FUNCTION__ & lt; & Lt; ""; Fu :: swap (other); Std :: swap (this-> y, other.y); }; }; Zero display (Foo and F1, Foo and F2, Bar and B 34, Bar and B 56) {Namespace Stead. Cout & lt; & Lt; "F1:" & lt; & Lt; F1.x & lt; & Lt; Endl; Cout & lt; & Lt; "F2:" & lt; & Lt; F2.x & lt; & Lt; Endl; Cout & lt; & Lt; "B 34:" & lt; & Lt; B34.x & lt; & Lt; "" & Lt; & Lt; B34.y & lt; & Lt; Endl; Cout & lt; & Lt; "B 56:" & lt; & Lt; B56.x & lt; & Lt; "" & Lt; & Lt; B56.y & lt; & Lt; Endl; } Ent Main (Int arzak, four ** argv) {{FU F1 (1), F2 (2); Bar B34 (3,4), B 56 (5,6); Std :: cout & lt; & Lt; Std :: endl & lt; & Lt; "Initial value:" & lt; & Lt; Std :: endl; Performance (F1, F2, B34, B56); } {FU F1 (1), F2 (2); Bar B34 (3,4), B 56 (5,6); Std :: cout & lt; & Lt; Std :: endl & lt; & Lt; "After identical swap:" & lt; & Lt; Std :: endl; F1.swap (F2); // desired b34.swap (b56); // desired display (F1, F2, B34, B56); } {FU F1 (1), F2 (2); Bar B34 (3,4), B 56 (5,6); Std :: cout & lt; & Lt; Std :: endl & lt; & Lt; "Odd Members After Swap:" & lt; & Lt; Std :: endl; // b56.swap (f2); // Not compiled, excellent f1.swap (b34); // Do not compile it, but make sure how the display (f1, f2, b34, b56); } Return 0; }  

Here is the output:

  Initial value: f1: 1 f2: 2 b34: 3 4 b56: 5 6 after uniform swap: virtual zero Foo :: Swap (Foo & amp;) Virtual Void Bar :: Swap (Bar & amp;) Virtual Zero Foo: Swap (FU) F1: 2F2: 1B 34: 5 6B 56: 3 4 Odd Members swap after: Virtual Zero Foo:: Swap (Foo and F) F1: 3F2: 2B 34: 1 4B 56: 5 6  

You can see where f1.swap (b34) "sliced" b 34 leads me to a potentially bad way Do not like it, either compiled or not blown at runtime. Due to participating heritage, I feel that if I use a non-member or friend swap implementation, then I would go to the same problem.

It is helpful but the code is available.

This usage case arises because Multi_array meets mult_array_ref, it only makes sense to swap multi_array_refs with multi-functional and multidimensional.

(some laughing solutions)

Add a protected virtual method, isBaseFoo () , Make it right in fu, and false in the bar, the swap method for foo can check that its argument is BaseFoo () == true.

Evil, and only detects the problem at the time, but I can not think of anything better, though Charles Bailey's answer may be better, if you allow dynamic_cast then <


No comments:

Post a Comment