I have this (simplified) situation:
class Tree {
class Iterator {
class Stack {
// ...
}
public:
// ...
}
public:
//...
}
I don't want to clutter the classes' definitions and I decide to write only method declarations inside classes themselves. Later on (waaay down below) when I want to define, say, copy assignment operator like this:
Tree::Iterator::Stack& Tree::Iterator::Stack::operator = (const Stack& p_stack) {
// ...
}
I have to deal with these nasty scope resolutions. I'm wondering if there's a way to shorten them, because using and typedef, as I know them, don't offer me anything.
EDIT: Since this is not CodeReview, and #Yulian requested clarification, here's the short version:
I'm making an iterative Red-Black Tree implementation. Mentioned class Iterator is for post-order traversing (so it's post-order-specific), and class Stack is its utility class. In this short program, only class Tree uses the Iterator, and only Iterator uses Stack.
After #Yulian's reminder, I recalled that it would be way more object-oriented if the mentioned classes were separately defined (maybe even as templates), but this is a small, self contained program and I'm trying to keep it that way.
EDIT: Self-contained also means that it's an isolated, single-file program, so no .h files or external code re-using whatsoever. Why? Because ACADEMIA (and associated arbitrary restrictions).
You could totally eliminate scopes resolutions with a using or typedef. But not with the traditional way because your nested classes are declared private. So you would have to use additional using in the public section of each nested class to "expose" them. Unfortunately, this breaks the "privateness" of them:
class Tree {
class Iterator {
class Stack {
Stack& operator = (const Stack& p_stack);
};
public:
using Stack_Out = Stack;
// ...
};
public:
using Iterator_Out = Iterator::Stack_Out;
//...
};
using Stack = Tree::Iterator_Out;
Stack& Stack::operator = (const Stack& p_stack) {
// ...
}
LIVE DEMO
You could however, remove scope levels (except for the outer one, i.e., Tree::) with out exposing the private nested classes in the following way:
class Tree {
class Iterator {
friend class Tree;
^^^^^^^^^^^^^^^^^^
class Stack {
Stack operator = (const Stack& p_stack);
};
public:
// ...
};
using Stack = Iterator::Stack;
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
public:
};
Tree::Stack Tree::Stack::operator = (const Stack& p_stack) {
^^^^^^^^^^^ ^^^^^^^^^^^
}
LIVE DEMO
First of all it is good to explain what you would like to achieve and way you think this method is good for your task.
IMHO, better approach is to create individual classes that are not nested and use them inside the Three class. This approach is called "HAS A". It is more clean easy to maintain and understand from others. If you provide more details we can come up with better class design.
You can let the preprocessor help you:
#define foobar Tree::Iterator::Stack
foobar& foobar::operator = (const Stack& p_stack) {
// ...
}
Related
I am working with an existing C library (that I can't modify) where some structures have opaque fields that must be accessed through specific setters and getters, like in the following crude example (imagining x is private, even though it's written in C).
struct CObject {
int x;
};
void setCObjectX(CObject* o, int x) {
o->x = x;
}
int getCObjectX(CObject* o) {
return o->x;
}
I am writing classes that privately own these types of structures, kind of like wrappers, albeit more complex. I want to expose the relevant fields in a convenient way. At first, I was simply writing setters and getters wherever necessary. However, I thought of something else, and I wanted to know if there are any downsides to the method. It uses function pointers (std::function) to store the C setter-getter pairs and present them as if directly accessing a field instead of functions.
Here is the generic class I wrote to help define such "fake" fields:
template<typename T>
struct IndirectField {
void operator=(const T& value) {
setter(value);
}
auto operator()() const -> T {
return *this;
}
operator T() const {
return getter();
}
std::function<void(const T&)> setter;
std::function<T()> getter;
};
It is used by defining an instance in the C++ class and setting up setter and getter with the corresponding C functions:
IndirectField<int> x;
// ...
x.setter = [=](int x) {
setCObjectX(innerObject.get(), x);
};
x.getter = [=]() {
return getCObjectX(innerObject.get());
};
Here is a complete, working code for testing.
Are there any disadvantages to using this method? Could it lead to eventual dangerous behaviors or something?
The biggest problem I see with your solution is that std::function objects take space inside each instance of IndirectField inside CPPObject, even when CObject type is the same.
You can fix this problem by making function pointers into template parameters:
template<typename T,typename R,void setter(R*,T),T getter(R*)>
struct IndirectField {
IndirectField(R *obj) : obj(obj) {
}
void operator=(const T& value) {
setter(obj, value);
}
auto operator()() const -> T {
return *this;
}
operator T() const {
return getter(obj);
}
private:
R *obj;
};
Here is how to use this implementation:
class CPPObject {
std::unique_ptr<CObject,decltype(&freeCObject)> obj;
public:
CPPObject()
: obj(createCObject(), freeCObject)
, x(obj.get())
, y(obj.get()) {
}
IndirectField<int,CObject,setCObjectX,getCObjectX> x;
IndirectField<double,CObject,setCObjectY,getCObjectY> y;
};
This approach trades two std::function objects for one CObject* pointer per IndirectField. Unfortunately, storing this pointer is required, because you cannot get it from the context inside the template.
Your modified demo.
Are there any disadvantages to using this method?
There's a few things to highlight in your code:
Your getters & setters, being not part of the class, break encapsulation. (Do you really want to tie yourself permanently to this library?)
Your example shows a massive amount of copying being done; which will be slower than it needs to be. (auto operator()(), operator T() to name but 2).
It's taking up more memory than you need to and adds more compexity than just passing around a Cobject. If you don't want things to know that it's a CObject, then create an abstract class and pass that abstract class around (see below for example).
Could it lead to eventual dangerous behaviors or something?
The breaking of encapsulation will result in x changing from any number of routes; and force other things to know about how it's stored in the object. Which is bad.
The creation of IndirectField Means that every object will have to have getters and setters in this way; which is going to be a maintenance nightmare.
Really I think what you're looking for is something like:
struct xProvider {
virtual int getX() const = 0;
virtual void setX() = 0;
};
struct MyCObject : xProvider {
private:
CObject obj;
public:
int getX() const override {return obj.x;}
CObject& getRawObj() {return obj;}
// etc ...
}
And then you just pass a reference / pointer to an xProvider around.
This will remove the dependence on this external C library; allowing you to replace it with your own test struct or a whole new library if you see fit; without having to re-write all your code using it
in a struct by default (as you post) all the fields are public, so they are accessible by client software. I you want to make them accessible to derived classes (you don't need to reimplement anything if you know the field contract and want to access it in a well defined way) they are made protected. And if you want them to be accessed by nobody, then mark them as private.
If the author of such a software doesn't want the fields to be touched by you, he will mark them as private, and then you'll have nothing to do, but to adapt to this behaviour. Failing to do will give you bad consequences.
Suppose you make a field that is modified with a set_myField() method, that calls a list of listeners anytime you make a change. If you bypass the method accessing function, all the listeners (many of them of unknown origin) will be bypassed and won't be notified of the field change. This is quite common in object programming, so you must obey the rules the authors impose to you.
I often encounter situations where I have to implement custom copy/move constructors. However some time later, it occurs that the class gets extended with a new member and this custom copy/move constructor is not updated, so I'm searching for a way to prevent the code from compiling without updating these methods.
Header code:
class MyClass
{
public:
MyClass(const MyClass &rhs);
// ...
private:
std::string _s;
std::unique_ptr<OtherClass> _owned;
bool _b;
};
Cpp code:
MyClass::MyClass(const MyClass &rhs)
: _s(rhs._s)
, _b(rhs._b)
{
if (rhs._owned)
_owned = rhs._owned->clone();
}
So, if I add some member to MyClass, example: std::size_t _size; than I would like a compilation error for the copy constructor.
My current solution is to add:
static_assert(sizeof(MyClass) == 32, "...");
near this implementation of the copy constructor. All of this works fine, unfortunately this only works when the size of the class increases. So if I instead add bool _b2; all compiles unfortunately.
So instead of checking the size, I would like to check the number of members. Unfortunately I haven't found this yet. Are there any suggestions?
I've already considered:
banning bool in favor of short, though it breaks all sense of intention.
replacing bool by bitset, however different values can't have different names
Put all default copyable members in separate struct, which introduces complexity
Add static const auto with number of members to the class, hoping this gets updated on adding a member
All these ideas however need code/guideline changes, so ideally I would just like to write static_assert(number_of_members<MyClass>::value == 3, "...");, any ideas?
Rule of Zero:
Classes that have custom destructors, copy/move constructors or copy/move assignment operators should deal exclusively with ownership (which follows from the Single Responsibility Principle). Other classes should not have custom destructors, copy/move constructors or copy/move assignment operators.
In this case, if you simply had a:
template <class T>
struct clone_unique_ptr {
std::unique_ptr<T> p;
clone_unique_ptr(const clone_unique_ptr& rhs)
: p(rhs.p ? rhs.p->clone() : nullptr)
{ }
// rest of special members
};
Then you wouldn't have to write anything special:
class MyClass
{
public:
MyClass(const MyClass&) = default;
private:
std::string _s;
clone_unique_ptr<OtherClass> _owned;
bool _b;
};
C++ does not have reflection built in. However, you can try using an external library xCppRefl which should provide reflection (Never used it before and it's quite old so let me know if using the library works for you).
Stepping through the source if you do
std::vector<DataMember> dataMembers = className.getDataMembers();
And then run assert(dataMembers.size() == expectedNumMembers) you should be able to test if the number of members in a class is what you expect.
Is it possible to declare a member function of a forward-declared class as friend? I am trying to do the following:
class BigComplicatedClass;
class Storage {
int data_;
public:
int data() { return data_; }
// OK, but provides too broad access:
friend class BigComplicatedClass;
// ERROR "invalid use of incomplete type":
friend void BigComplicatedClass::ModifyStorage();
};
So the goal is to (i) restrict the friend declaration to a single method, and (ii) not to include the definition of the complicated class to reduce compile time.
One approach might be to add a class acting as an intermediary:
// In Storage.h:
class BigComplicatedClass_Helper;
class Storage {
// (...)
friend class BigComplicatedClass_Helper;
};
// In BigComplicatedClass.h:
class BigComplicatedClass_Helper {
static int &AccessData(Storage &storage) { return storage.data_; }
friend void BigComplicatedClass::ModifyStorage();
};
However, this seems a bit clumsy... so I assume that there must be a better solution!
As #Ben says, it's not possible, but you can give specific access just to that member function through a "passkey". It works a bit like the intermediate helper class, but is imho clearer:
// Storage.h
// forward declare the passkey
class StorageDataKey;
class Storage {
int data_;
public:
int data() { return data_; }
// only functions that can pass the key to this function have access
// and get the data as a reference
int& data(StorageDataKey const&){ return data_; }
};
// BigComplicatedClass.cpp
#include "BigComplicatedClass.h"
#include "Storage.h"
// define the passkey
class StorageDataKey{
StorageDataKey(){} // default ctor private
StorageDataKey(const StorageDataKey&){} // copy ctor private
// grant access to one method
friend void BigComplicatedClass::ModifyStorage();
};
void BigComplicatedClass::ModifyStorage(){
int& data = storage_.data(StorageDataKey());
// ...
}
No, you can't declare individual member functions as friends until they've been declared. You can only befriend the entire class.
It may or may not be relevant here, but it is useful to remind ourselves that there is a wild world beyond the scope of classes and objects where functions can roam free.
For example, I recently needed to close off a (singleton global static) system error log from a global exception handler based on a port of someone else's code. The normal include file for my error log conflicted with the exception handler code because both wanted to include "windows.h" for reasons I didn't look into. When this and other questions persuaded me I could not make a forward declaration of my ErrorLog class's member functions, what I did was wrap the necessary functions into a global scope function like this:
void WriteUrgentMessageToErrorLog( const char * message )
{
ErrorLog::LogSimpleMessage( message );
ErrorLog::FlushAccumulatedMessagesToDisk();
}
Some people are very particular about maintaining the integrity of their class structure at all cost... and seldom acknowledge that applications using those classes are inevitably built on top of something that lacks that structure. But it's out there, and used judiciously, it has its place.
Given the age of this question, I have not looked deeply into its relevance here. All I wanted to share was the opinion that sometimes a simple wrapping mechanism like this is a much cleaner and more readily understood alternative to something that has a lot more subtlety and cleverness about it. Subtlety and cleverness tends to get changed at some later date by someone required to add to it who didn't fully understand it. Before you know it, you have a bug...
Can someone please point me towards some nice resources for understanding and using nested classes? I have some material like Programming Principles and things like this IBM Knowledge Center - Nested Classes
But I'm still having trouble understanding their purpose. Could someone please help me?
Nested classes are cool for hiding implementation details.
List:
class List
{
public:
List(): head(nullptr), tail(nullptr) {}
private:
class Node
{
public:
int data;
Node* next;
Node* prev;
};
private:
Node* head;
Node* tail;
};
Here I don't want to expose Node as other people may decide to use the class and that would hinder me from updating my class as anything exposed is part of the public API and must be maintained forever. By making the class private, I not only hide the implementation I am also saying this is mine and I may change it at any time so you can not use it.
Look at std::list or std::map they all contain hidden classes (or do they?). The point is they may or may not, but because the implementation is private and hidden the builders of the STL were able to update the code without affecting how you used the code, or leaving a lot of old baggage laying around the STL because they need to maintain backwards compatibility with some fool who decided they wanted to use the Node class that was hidden inside list.
Nested classes are just like regular classes, but:
they have additional access restriction (as all definitions inside a class definition do),
they don't pollute the given namespace, e.g. global namespace. If you feel that class B is so deeply connected to class A, but the objects of A and B are not necessarily related, then you might want the class B to be only accessible via scoping the A class (it would be referred to as A::Class).
Some examples:
Publicly nesting class to put it in a scope of relevant class
Assume you want to have a class SomeSpecificCollection which would aggregate objects of class Element. You can then either:
declare two classes: SomeSpecificCollection and Element - bad, because the name "Element" is general enough in order to cause a possible name clash
introduce a namespace someSpecificCollection and declare classes someSpecificCollection::Collection and someSpecificCollection::Element. No risk of name clash, but can it get any more verbose?
declare two global classes SomeSpecificCollection and SomeSpecificCollectionElement - which has minor drawbacks, but is probably OK.
declare global class SomeSpecificCollection and class Element as its nested class. Then:
you don't risk any name clashes as Element is not in the global namespace,
in implementation of SomeSpecificCollection you refer to just Element, and everywhere else as SomeSpecificCollection::Element - which looks +- the same as 3., but more clear
it gets plain simple that it's "an element of a specific collection", not "a specific element of a collection"
it is visible that SomeSpecificCollection is also a class.
In my opinion, the last variant is definitely the most intuitive and hence best design.
Let me stress - It's not a big difference from making two global classes with more verbose names. It just a tiny little detail, but imho it makes the code more clear.
Introducing another scope inside a class scope
This is especially useful for introducing typedefs or enums. I'll just post a code example here:
class Product {
public:
enum ProductType {
FANCY, AWESOME, USEFUL
};
enum ProductBoxType {
BOX, BAG, CRATE
};
Product(ProductType t, ProductBoxType b, String name);
// the rest of the class: fields, methods
};
One then will call:
Product p(Product::FANCY, Product::BOX);
But when looking at code completion proposals for Product::, one will often get all the possible enum values (BOX, FANCY, CRATE) listed and it's easy to make a mistake here (C++0x's strongly typed enums kind of solve that, but never mind).
But if you introduce additional scope for those enums using nested classes, things could look like:
class Product {
public:
struct ProductType {
enum Enum { FANCY, AWESOME, USEFUL };
};
struct ProductBoxType {
enum Enum { BOX, BAG, CRATE };
};
Product(ProductType::Enum t, ProductBoxType::Enum b, String name);
// the rest of the class: fields, methods
};
Then the call looks like:
Product p(Product::ProductType::FANCY, Product::ProductBoxType::BOX);
Then by typing Product::ProductType:: in an IDE, one will get only the enums from the desired scope suggested. This also reduces the risk of making a mistake.
Of course this may not be needed for small classes, but if one has a lot of enums, then it makes things easier for the client programmers.
In the same way, you could "organise" a big bunch of typedefs in a template, if you ever had the need to. It's a useful pattern sometimes.
The PIMPL idiom
The PIMPL (short for Pointer to IMPLementation) is an idiom useful to remove the implementation details of a class from the header. This reduces the need of recompiling classes depending on the class' header whenever the "implementation" part of the header changes.
It's usually implemented using a nested class:
X.h:
class X {
public:
X();
virtual ~X();
void publicInterface();
void publicInterface2();
private:
struct Impl;
std::unique_ptr<Impl> impl;
}
X.cpp:
#include "X.h"
#include <windows.h>
struct X::Impl {
HWND hWnd; // this field is a part of the class, but no need to include windows.h in header
// all private fields, methods go here
void privateMethod(HWND wnd);
void privateMethod();
};
X::X() : impl(new Impl()) {
// ...
}
// and the rest of definitions go here
This is particularly useful if the full class definition needs the definition of types from some external library which has a heavy or just ugly header file (take WinAPI). If you use PIMPL, then you can enclose any WinAPI-specific functionality only in .cpp and never include it in .h.
I don't use nested classes much, but I do use them now and then. Especially when I define some kind of data type, and I then want to define a STL functor designed for that data type.
For example, consider a generic Field class that has an ID number, a type code and a field name. If I want to search a vector of these Fields by either ID number or name, I might construct a functor to do so:
class Field
{
public:
unsigned id_;
string name_;
unsigned type_;
class match : public std::unary_function<bool, Field>
{
public:
match(const string& name) : name_(name), has_name_(true) {};
match(unsigned id) : id_(id), has_id_(true) {};
bool operator()(const Field& rhs) const
{
bool ret = true;
if( ret && has_id_ ) ret = id_ == rhs.id_;
if( ret && has_name_ ) ret = name_ == rhs.name_;
return ret;
};
private:
unsigned id_;
bool has_id_;
string name_;
bool has_name_;
};
};
Then code that needs to search for these Fields can use the match scoped within the Field class itself:
vector<Field>::const_iterator it = find_if(fields.begin(), fields.end(), Field::match("FieldName"));
One can implement a Builder pattern with nested class. Especially in C++, personally I find it semantically cleaner. For example:
class Product{
public:
class Builder;
}
class Product::Builder {
// Builder Implementation
}
Rather than:
class Product {}
class ProductBuilder {}
I think the main purpose of making a class to be nested instead of just a friend class is the ability to inherit nested class within derived one. Friendship is not inherited in C++.
You also can think about first class ass type of main function, where You initiate all needed classes to work togheter. Like for example class Game, initiate all other classes like windows, heroes, enemy's, levels and so on. This way You can get rid all that stuff from main function it self. Where You can create obiect of Game, and maybe do some extra external call not related to Gemente it self.
I'm having some toubt here. Hope you guys can share out some programming tips. Just curious to know whether is it a good programming practice if I do something like the code below.
class Outer {
public:
class Inner {
public:
Inner() {}
}
Outer() {}
};
I have been doing this for structure where I only want my structure to be expose to my class instead of global. But the case is different here, I am using a class now? Have you guys facing such a situation before? Very much appreciated on any advice from you ;)
I'll break the answer into two parts:
for cases where you only organize code, you should use namespaces instead of classes -- if the inner class isn't an entity that is only worked with from inside the class (especially only constructed in the class), then inner classes are a good idea -- another example STL function objects.
in C++ there is absolutely NO DIFFERENCE between structures and classes except that structures have public members by default. Hence there's no real difference when you have classes -- it's more a matter of style.
This is a good practice in many cases. Here's one where we implement a link list:
template <class T>
class MyLinkList {
public:
class Node {
public:
Node* next;
T data;
Node(const T& data, Node* node) : next(node), data(data) {}
};
class Iterator {
public:
Node* current;
Iterator(Node* node) : current(node) {}
T& operator*() { return current->data; }
void operator++(int) { current = current->next; }
bool operator!=(int) { return current != NULL; }
};
private:
Node* head;
}
The above is just snippet that is not intended to be complete or compilable. The point is to show that Node and Iterator are inner classes to the MyLinkList class. The reason why this makes sense is to convey the fact that Node and Iterator are not independent to be stand alone by themselves, but they need to be qualified by MyLinkList (for instance MyLinkList::Iterator it)
This is purely a matter of style, however I think it is typically more common in the C++ community to use a namespace named detail for classes that are purely helpers or are purely used in the implementation of other classes. There are several advantages to using namespaces in place of inner classes, among them include: greater compatibility (how compilers resolve names in inner classes can be incredibly different between Visual C++ and GCC, for example), more encapsulation (in the inner/outer variant, the inner class has greater access to members of instances of the outer class), easier implementation (you don't have to fully qualify the helper class every single time in the implementation file, since you can put a using directive in the ".cpp" source file). If you are going to use an inner class, then you need to make the conscious decision to make that a part of your API.
Using Namespaces
namespace collection
{
namespace detail
{
class LinkedListNode
{
//...
};
}
class LinkedList
{
// ...
};
}
Using Inner Classes
namespace collection
{
class LinkedList
{
// ...
class LinkedListNode
{
// ...
};
// ...
};
}
It's not an everyday thing, but it's not unheard of, either. You would do this if there were a class (Inner) that only makes sense to a client program when the client is using Outer.
If you only want a class to be exposed in a certain file, you can use an unnamed namespace within that file. Then whatever code is within that namespace is only available within that file.
namespace
{
//stuff
}