i'm new to c++, i was wondering if somebody could clarify something for me about encapsulation, for example if you have 2 classes

class Music {

private:
int a;

public:
int b();
int C();

};

class Record: public Music {

private:
char c;
int a;
float b();

protected:
int d();
void e();

public:
char f();
int g();
};

what are the member functions here of class Record that can access private data of class Record, and which member functions of class Record can access private data of class Music. and if there is a external routine that has an object instance of class Record, what member functions of class Record can it access. also if a new class newRecord is derived from class Record, what member functions in Record can newRecord access?

also does anybody know why compiler says it is dangerous to convert base class pointer into a derived class pointer, whats dangerous about it.

Dani AI

Generated

Short, practical summary tied to the posts already here.

  • Access rules (quick): any member function of Record (public, protected or private) can read/write Record's private data. Record cannot access Music's private members — private is private to the declaring class (only Music members, friends, or nested classes can). An external function that has a Record object may call only Record's public members (unless it is a friend). A class derived from Record (newRecord) can access Record's public and protected members, but not Record's private members. was right about own-class access but incomplete about derived access (protected members are available to newRecord).

  • Name hiding and how to call base operations: if Record declares a member with the same name as Music's member, the base version is hidden in Record's scope. The derived class can call base functions using qualification or bring base overloads into scope; it still cannot access base private members directly.

  • Why converting a base pointer to a derived pointer is dangerous: as said, that conversion is only safe when the pointed-to object really is a Derived. Otherwise you get undefined behavior. The safe runtime way is dynamic_cast on a polymorphic base (base must have at least one virtual function). Example pattern:

Music *m = /* created by caller */;
Record *r = dynamic_cast<Record*>(m);
if (r) {
    // safe to use r as Record*
} else {
    // m is not actually a Record
}

Use dynamic_cast (check for null) or design factories that return the correct type. Avoid C-style casts, reinterpret_cast, or blind static_casts for downcasts. Also make the base destructor virtual if derived objects will be deleted through base pointers, and be aware of object slicing when copying by value.

Recommended Answers

All 2 Replies

Code tags please.

>what are the member functions here of class Record that can access private data of class Record.

Any member function of it own class can access the private data of its class.

>and which member functions of class Record can access private data of class Music.

None of record's member functions can access music's private data.

>and if there is a external routine that has an object instance of class Record, what member functions of class Record can it access.

Any functions that are public in Record.

>also if a new class newRecord is derived from class Record, what member functions in Record can newRecord access

Ussually the public ones.

>also does anybody know why compiler says it is dangerous to convert base class pointer into a derived class pointer, whats dangerous about it.

I am not sure.

also does anybody know why compiler says it is dangerous to convert base class pointer into a derived class pointer, whats dangerous about it.

It sounds like you are trying to do something like the following...

Music *music = new Music;

Record *record = (Record *)music;

This is fine and it will compile, but you *never* want to do that. Remember that Record, though it contains very similar data to Music, is actually a different class. The original music object that you created in memory only contains data from the Music class, and nothing from the Record class. If you try to access data from any class with a pointer to an object that isn't a member of that class, then the program will crash or worse - something very unexpected will happen.

On the other hand, you can do the reverse just fine. This is one of the more awesome things in object oriented programming. :)

Record *record = new Record;

Music *music = (Music *)record;

//  Call Music methods, access Music's member variables, whatever..

This is extremely powerful because you can create new derived objects, and store them in memory within a single list as pointers of a base class. Combining this with overloaded operators/functions can make for a very elegantly designed program that is easy to add onto...

Hope that was at least a little bit helpful. :)

-Fredric

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.