![]() |
| | #1 |
| C++0x User Join Date: Nov 2008 Location: Sweden
Posts: 133
| namespace and data hiding Code: namespace Foobar {
class Bar {
private:
class Foo: private Enemy {
private:
Suit value;
} foos[3];
};
}
Any suggestions? |
| Tux0r is offline | |
| | #2 | |
| C++ Witch Join Date: Oct 2003 Location: Singapore
Posts: 10,359
| Quote:
By the way, why do you want to do this?
__________________ C + C++ Compiler: MinGW port of GCC Build + Version Control System: SCons + Bazaar Look up a C/C++ Reference and learn How To Ask Questions The Smart Way | |
| laserlight is online now | |
| | #3 |
| C++0x User Join Date: Nov 2008 Location: Sweden
Posts: 133
| Thanks for your answer. Ok the way I'm seeing it now is that I want an array of 3 Foo in Bar and to do that the right way I would have to hide Foo from rest of the program, no one else needs it! If I nest another namespace it is still visible to the rest of the program only at another scope. |
| Tux0r is offline | |
| | #4 | ||
| C++ Witch Join Date: Oct 2003 Location: Singapore
Posts: 10,359
| Quote:
Quote:
__________________ C + C++ Compiler: MinGW port of GCC Build + Version Control System: SCons + Bazaar Look up a C/C++ Reference and learn How To Ask Questions The Smart Way | ||
| laserlight is online now | |
| | #5 | |
| C++0x User Join Date: Nov 2008 Location: Sweden
Posts: 133
| Quote:
It would be nice if I could use an anonymous namespace to wrap it up with but it does not have the effect I desire. | |
| Tux0r is offline | |
| | #6 | ||
| C++ Witch Join Date: Oct 2003 Location: Singapore
Posts: 10,359
| Quote:
Quote:
__________________ C + C++ Compiler: MinGW port of GCC Build + Version Control System: SCons + Bazaar Look up a C/C++ Reference and learn How To Ask Questions The Smart Way | ||
| laserlight is online now | |
| | #7 |
| Registered User Join Date: Apr 2006 Location: United States
Posts: 3,201
| Well when you're talking about access do you mean you want to not have objects of specific classes or that they shouldn't be derived from? Because there are different ways. If class A should not be an object because it's nonsensical, then A should be an abstract data type. A will only exist through its children. If you want to prevent inheritance the path with least resistance is with a non-virtual destructor. Non-virtual destructors do not properly clean up after a derived object has been sliced, so competent programmers do not extend such classes.
__________________ Os iusti meditabitur sapientiam Et lingua eius loquetur indicium "There is nothing either good or bad, but thinking makes it so." (Shakespeare, Hamlet, Act II scene ii) http://www.myspace.com/whiteflags99 |
| whiteflags is offline | |
| | #8 |
| C++ Witch Join Date: Oct 2003 Location: Singapore
Posts: 10,359
| Come to think of it, I do know a way to accomplish roughly what you want, but it requires you to switch from private inheritance to composition. You could use the pointer to an implementation (pimpl) idiom. Since you only have a forward declaration of Enemy in the header file, your users cannot do much with the Enemy class anyway, but you can do all you want in the corresponding source file.
__________________ C + C++ Compiler: MinGW port of GCC Build + Version Control System: SCons + Bazaar Look up a C/C++ Reference and learn How To Ask Questions The Smart Way |
| laserlight is online now | |
| | #9 |
| C++0x User Join Date: Nov 2008 Location: Sweden
Posts: 133
| Ok. This is what I think I'll settle down with. Code: enum class Suit: unsigned char{SPADE,HEART,DIAMOND,CLUB};
class Cards {
private:
class Card: private Enemy {
private:
Suit value;
public:
Suit suit() const;
} cards[3];
public:
void update();
};
Suit Cards::Card::suit() const {
return value;
}
void Cards::update() {
if(cards[0].suit()==cards[1].suit() && cards[1].suit()==cards[2].suit())
delete this;
}
|
| Tux0r is offline | |
| | #10 |
| C++ Witch Join Date: Oct 2003 Location: Singapore
Posts: 10,359
| Eh, do not use delete this. I believe that it is only defined if the object was created by new, and even then the user has no way of knowing that the object has been destroyed.
__________________ C + C++ Compiler: MinGW port of GCC Build + Version Control System: SCons + Bazaar Look up a C/C++ Reference and learn How To Ask Questions The Smart Way |
| laserlight is online now | |
| | #11 |
| C++0x User Join Date: Nov 2008 Location: Sweden
Posts: 133
| Three-of-a-Kind - Zeldapedia, The Legend of Zelda wiki - Twilight Princess, Ocarina of Time, Spirit Tracks, and more That's the enemy in the game I'm writing, they come in 3 and to defeat them they should be set to the same value. When the values of them are the same then the destructor is called. The destructor will call an event. Like, creating a chest with treasure because the enemies were defeated. I believe it makes perfect sense, and because I'm using polymorphism I have to new (afaik). Code: enum class Suit: char{NONE,SPADE,HEART,DIAMOND,CLUB};
class Cards: private Enemy {
private:
class Card: private Enemy {
private:
Suit value;
public:
Suit suit() const;
void set_suit(Suit&&);
void update();
} cards[3];
public:
void update();
};
Suit Cards::Card::suit() const {
return value;
}
void Cards::Card::set_suit(Suit&& val) {
value=val;
}
void Cards::update() {
for(int i{}; i<3; ++i)
cards[i].update();
//Check for equality
if(cards[0].suit()!=Suit::NONE && cards[1].suit()!=Suit::NONE && cards[2].suit()!=Suit::NONE) {
if(cards[0].suit()==cards[1].suit() && cards[1].suit()==cards[2].suit()) {
delete this;
}
else {
for(int i{}; i<3; ++i)
cards[i].set_suit(Suit::NONE);
}
}
}
|
| Tux0r is offline | |
| | #12 |
| Registered User Join Date: Apr 2006 Location: United States
Posts: 3,201
| I find it weird though that when you essentially win no attempt is made to communicate the fact to the outside and your object just dies. You should let the scope that created your object be where the object is destroyed wherever possible. Even dynamic storage tends to be managed this way. It mirrors automatic storage, which is easy to understand, and typically is well defined.
__________________ Os iusti meditabitur sapientiam Et lingua eius loquetur indicium "There is nothing either good or bad, but thinking makes it so." (Shakespeare, Hamlet, Act II scene ii) http://www.myspace.com/whiteflags99 |
| whiteflags is offline | |
| | #13 |
| C++0x User Join Date: Nov 2008 Location: Sweden
Posts: 133
| Ok well there's the other option of adding a bool member variable to Cards, maybe destroyed. Then my delete loop on std::vector<Enemy*> will take care of the rest when it's time. |
| Tux0r is offline | |
| | #14 |
| Super Moderator Join Date: Aug 2001
Posts: 7,472
| C++ does not have the notion of public and private classes as other languages do. If the class is in a namespace and the namespace is visible to the object then the object can use any class in the namespace - generally speaking. You cannot 'hide' classes in namespaces. The only way I know to 'hide' classes is either hide them in the impl of an interface, use pimpl (public functions operate on a private instance of the impl), or do what you have done and make the class private to another. Anytime I see a class nested in another class to me it implies the outside class has ownership of the nested class. Another very ugly way to do this is to make a class completely private and then use friend to expose the class to any class needing to use it. Some completely dislike friend as it breaks encapsulation but in this case it is more enforcing encapsulation than breaking it. You are forcing a user of the class to access the nested class members and data via the owning class. One huge problem with friend, even when used appropriately, is that it is not inherited. So any classes derived from a base that has friends does not inherit those friends. This will break a facade pattern rather quickly and does not work well with interfaces.
__________________ If you aim at everything you will hit something but you won't know what it is. |
| Bubba is offline | |
| | #15 | |||
| Registered User Join Date: Jun 2005
Posts: 1,343
| Quote:
Quote:
Quote:
Interfaces specify the semantics for usage of a class. They do not specify how compliance with the interface is implemented. Friendship simply allows a class definition to explicitly specify that other entities (eg other classes or other functions) are part of that interface. Or, to put it another way, if inability to inherit friendship breaks the implementation of a derived class then either the design of the base class is broken (i.e. it does not provide access to capabilities required by derived classes) or the derived class implementation is trying to do something invalid (access private members of a base class without permission). I suspect you're referring to the fact that poor design of a base can make life inconvenient for implementers of derived classes. That does not mean the derived class implementer should have access to private members of a base class that are not granted by that base class. It means the base class should be modified so it allows the derived class to perform operations it needs.
__________________ Right 98% of the time, and don't care about the other 3%. | |||
| grumpy is offline | |
![]() |
| Tags |
| class, namespace |
| Thread Tools | |
| Display Modes | |
|
Similar Threads | ||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| question about a working linked list | cold_dog | C++ Programming | 23 | 09-13-2006 01:00 AM |
| data validation & namespace | tiange | C++ Programming | 4 | 07-05-2005 02:45 AM |
| Templated Binary Tree... dear god... | Nakeerb | C++ Programming | 15 | 01-17-2003 02:24 AM |
| can't insert data into my B-Tree class structure | daluu | C++ Programming | 0 | 12-05-2002 06:03 PM |
| Post programs | GaPe | C# Programming | 8 | 05-12-2002 11:07 AM |