Beispiel #1
0
int main()
{
    Base a(2);
    a.print();

    Sub s;
    s.print();

    return 0;
}
Beispiel #2
0
int main(int argc, char** argv) {
    
    // 6.1
    
    // Private member can NOT be called by subclass
    Sub object;
    object.put(100); // error: ‘void Super::put(int)’ is inaccessible within this context
    object.put(object.get() + 1);
    cout << object.get() << endl;
    // 'storage' is not accessible by declare 'private', should be 'protected'
    object.print();
    // error: ‘int Super::storage’ is protected within this context
    // 'storage' is still not accessible even as 'protected', should be public
    // cout << object.storage << endl;
    
    
    // 6.2
    /*
    // subclass pointer CAN be converted to superclass pointer implicitly.
    Pet *a_pet1 = new Cat("Tom");
    Pet *a_pet2 = new Dog("Spike");
    Pet *a_pet3 = new Bird("Poly");
    a_pet1 -> Run(); 
    a_pet2 -> Run();
    a_pet3 -> Run();
     // is not allowed here! since a_pet1 is superclass pointer
    // a_pet1 -> MakeSound(); // error: ‘class Pet’ has no member named ‘MakeSound’
    // a_pet2 -> MakeSound(); // error: ‘class Pet’ has no member named ‘MakeSound’
    // Use static_cast to explicitly convert superclass pointer to subclass pointer
    static_cast<Cat *>(a_pet1) -> MakeSound();
    static_cast<Dog *>(a_pet2) -> MakeSound();
    static_cast<Bird *>(a_pet3) -> Laugh(1);
    cout << static_cast<Cat *>(a_pet1) -> CatName << endl;
    cout << static_cast<Dog *>(a_pet2) -> DogName << endl;
    // static_cast does NOT do any type check. which may cause unintended error
    // Interesting result: the common base class member is saved and right, the extra target subclass members are just concatenated
    static_cast<Cat *>(a_pet2) -> MakeSound(); // dog meow
    static_cast<Dog *>(a_pet1) -> MakeSound();	// cat bark
    static_cast<Dog *>(a_pet3) -> MakeSound();	// bird MakeSound() NOT Laugh(int)
    cout << static_cast<Cat *>(a_pet2) -> CatName << endl;
    cout << static_cast<Dog *>(a_pet1) -> DogName << endl;
    // Caution
    cout << static_cast<Dog *>(a_pet3) -> DogName << endl; // No compile time error, debug shows out of bounds
    // Runtime error:  "Segmentation fault; core dumped;" means that you tried to access memory that you do not have access to.
    // Runtime stops here, no further execution due to out of bounds
    Dog *a_birddog = static_cast<Dog *>(a_pet3);
    a_birddog -> MakeSound();
    Bird *a_bird = static_cast<Bird *>(a_pet3);
    a_bird -> Laugh(1);
    // dynamic_cast can downcast (convert from pointer-to-base to pointer-to-derived) polymorphic classes (those with virtual members) if -and only if- the pointed object is a valid complete object of the target type.
    // dynamic_cast<Cat *>(a_pet1) -> MakeSound(); // error: cannot dynamic_cast ‘a_pet1’ (of type ‘class Pet*’) to type ‘class Cat*’ (source type is not polymorphic)
    // dynamic_cast<Dog *>(a_pet2) -> MakeSound(); // error: cannot dynamic_cast ‘a_pet2’ (of type ‘class Pet*’) to type ‘class Dog*’ (source type is not polymorphic)
    */
    
    // 6.3
    /*
    Cat *a_cat;
    Dog *a_dog;
    a_cat = new Cat("Kitty");
    a_dog = new Dog("Doggie");
    a_cat -> MakeSound();
    static_cast<Pet *>(a_cat) -> MakeSound();
    a_dog -> MakeSound();
    static_cast<Pet *>(a_dog) -> MakeSound();
    // dynamic_cast == Implicit conversion
    dynamic_cast<Pet *>(a_dog) -> MakeSound(); // the Pet says: Shh! Shh!
    // Implicit conversion
    Pet *a_pet = a_cat;
    a_pet -> MakeSound(); // the Pet says: Shh! Shh!
    */
    
    // Assessment: 70%
    // Q1: Compilation fails
    /*
    Y y;
    cout << y.v; // error: 'int X::v' is private
    */
    
    // Q2: 0 is wrong, Compilation fails is right
    /*
    Y *y = new Y(); // error: 'Y::Y()' is private
    // Explicit Constructors have to be public
    // Y *y = new Y; // error: 'Y::Y()' is private
    cout << y->v; // error: 'int X::v' is protected
    delete y;
    */
    
    // Q3: Compilation fails
    /*
    Z *z = new Z();
    Y *y = new Y();
    z = y; // error: cannot convert 'Y*' to 'Z*' in assignment
    cout << (z == y); // error: comparison between distinct pointer types 'Z*' and 'Y*' lacks a cast
    */
    
    // Q4: Y
    /*
    X *x = new Y();
    static_cast<Y *>(x) -> shout();
    */
    
    // Q5: X is wrong, Z is right
    // If base is virtual, all subclasses are virtual as well, no matter how many inheritance
    /*
    Y *y = new Z();
    dynamic_cast<X *>(y) -> shout(); // Z
    y -> shout(); // Z
    */
    
    // Q6: 1
    /*
    A a;
    Do(a);
    a.inc();
    cout << a.val;
    */
    
    // Q7: 2
    /*
    A a;
    Do(&a);
    cout << a.inc();
    */
    
    // Q8: 22
    /*
    A a,b = a;
    cout << a.get() << b.get();
    */
    
    // Q9: Compilation fails is wrong, 33 is right
    /*
    A a(2);
    // There is an explicit copy constructor, no error here
    A b(a);
    cout << a.get() << b.get();
    */
    
    // Q10: 1
    /*
    A a; B b;
    a.set(1);
    b.kill(a);
    cout << a.get();
    */
    
    // Assessment Retake: 100%
    // Q4: X
    /*
    Y *y = new Z();
    dynamic_cast<X *>(y) -> shout();
    */
    
    // Q6: 220
    // If no override, use the parent one, even it's virtual
    A *a = new C();;
    Do(a);
    
    return 0;
}