I am reading some of the Epic Games UnrealEngine4 source code and see couple of practices which make me wonder if I miss some of essential C++ magic.
static inline member methods in class declaration.Here #dividebyzero user actually sheds very important info regarding the effect of using static inline,at least with GCC compiler - inline placement similar to how MACRO functions behave.
Another interesting practice I can see is how UE4 creates interfaces for inheritance.Here is example based on how OpenGL backend module in UE4 looks like:
class FOpenGLBase
{
public:
static FORCEINLINE void UnmapBufferRange(GLenum Type, uint32 InOffset, uint32 InSize) UGL_REQUIRED_VOID
};
Where UGL_REQURED_VOID is replaced with default function body,which reports "unimplemented" method error if called on this base class.
Next come inheritance of the above class:
struct FOpenGL3 : public FOpenGLBase
{
static FORCEINLINE void UnmapBuffer(GLenum Type)
{
glUnmapBuffer(Type);
}
static FORCEINLINE void UnmapBufferRange(GLenum Type, uint32 InOffset, uint32 InSize)
{
UnmapBuffer(Type);
}
};
I even didn't know it was possible for a struct to inherit from class and vice -versa.
I understand that static + inline makes it possible to generate unique function body per function call,which makes it possible to put different body but with same signature in subclass's declaration.
But then I also wonder why one needs virtual inheritance for small methods if it is possible to override static inline methods in subclass just like this?
Why such an approach is not common? (at least from my experience I find it uncommon)
PS: I wasn't sure if this question format is ok for SO or should be rather put in CodeReview site.
First of all, the post you refer to seems to be about static inline functions in the namespace scope. Your example has them in a class scope. There's a very big difference between these two scopes.
In class scope, the static keyword makes the method callable on the class, instead of on an instance. So in this scope, there's a very real difference between static, static inline and just inline.
Next, static methods in class scopes have nothing to do with inheritance, exactly because static members are part of the class rather than instances. Inheritance is only relevant for instances. To make this clear, consider how you would call UnmapBufferRange on either FOpenGLBase or FOpenGL3:
FOpenGLBase::UnmapBufferRange(..); // Call the FOpenGLBase version
FOpenGL3::UnmapBufferRange(..); // Call the FOpenGL3 version
There's no inheritance because you couldn't even override it - you simply redefine it for another class. This effectively hides it, so it looks like inheritance but it's not the same!
Related
Out of idle curiosity, I've typed in the following piece of code:
pure struct Foo{ }
pure class Bar{ }
This, apparently, compiles with both DMD and LDC. I have no idea what it does (if it does), as calling impure functions from such structs/classes is OK. So, what does attaching pure to a class or a struct change?
In general, D has a tendency to ignore attributes when they don't apply, if nothing else, because generic code is easier to write that way (at times, it avoids having to write a bunch of static ifs just to avoid applying attributes to code where they wouldn't have any effect) - one example being that you can put static on a pretty much any declaration at module level, but it doesn't actually do anything for most of them, and the compiler doesn't complain about it.
However, for whatever reason, the way that attributes get applied when you mark a struct or class with them is a bit inconsistent. For instance, if you marked a struct or class with #safe, then every function in that struct or class will be #safe unless it's marked with #trusted or #system. In contrast, if you mark the class or struct with pure, it does absolutely nothing - just like with static. It's simply ignored.
My best guess as to why something like #safe is applied to all of the functions inside the struct or class, whereas an attribute like pure or nothrow is ignored is that #safe, #trusted, and #system can be undone on specific functions within the struct or class by using a different attribute explicitly on that function, whereas for most attributes, there is no way to reverse them.
Unfortunately however, the fact that you can mark a class or struct with attributes when they either don't apply or when they apply just to the declarations within the class or struct and not the class or struct itself does tend to confuse people (e.g. some people think that immutable class C {..} means something special for the class, when all it means is that the declarations within the class are immutable; it would be no different from doing class C { immutable { ... } }). So, ultimately, you have to be familiar with what each attribute actually does to know when they actually apply to the class or struct, when they really just apply to the declarations inside the class or struct, and when they're simply ignored.
Personally, I never apply attributes to a class or struct unless they're specifically meant to apply to the struct or class and not on the functions within it (e.g. final on a class means something separate from putting it on the functions within that class), and the number of attributes that actually apply to a struct or class is pretty small. static does in some contexts (just not at module level), abstract and final do for classes, and the access modifiers (public, private, etc.) do. Per TDPL, synchronized is also supposed to be special for the class, but synchronized classes have never really been implemented (just synchronized functions). So, I might have missed one, but off the top of my head, that's the full list of attributes that can actually apply to a struct or class, and all of the others are either ignored or apply to the declarations within the struct or class but not to the struct or class itself.
It changes nothing. The D compiler simply ignores many keywords when they're placed in locations they wouldn't make sense.
A quick test to prove this:
pure struct S {
static void bar() {}
}
pure unittest {
static assert(!__traits(compiles, S.bar()));
}
I am looking for an article or documentation that explains why a free static function is better than a private member function, when the given function does not modify or read the private members of the class. To my point of view the advantages are :
Less dependencies
Better encapsulation (for "mammoth" classes, it helps to know that at least those function calls do not modify the members)
I am certain someone has already written something better than what I can do.
Free static functions are passe. One would use a function in the anonymous namespace instead.
They are slightly more maintainable -- since they can't access private members, they are robust against changes to implementation details. A static member function could also be independent of implementation details, but you don't have the compiler verifying that.
If you are specifically looking for an article you should read "Item 23: Prefer non-member non-friend functions to member functions" in Effective C++ by Scott Meyers. I would suggest that this book is essential reading for all serious C++ programmers.
The basic premise for this topic is that if you can implement a free function using existing interface methods of a class then you should as this actually simplifies the class. That is, the less code that can see the internals of the class the more encapsulated it is. Adding more bloat actually decreases encapsulation.
You seem to be misusing some words so I'll attempt to clarify
class myclass {
private:
int data;
void func1(); // private mutator function
void func2() const; // private accessor function
static void func3(); // private static function
public:
int moredata;
void func4(); // public mutator function
void func5() const; // public accessor function
static void func6(); // public static function
}
void func7(myclass); // free function
static void func8(myclass); // static function can't be accessed outside file.
Generally, operator overloads tend to free functions so that way they can be found during lookup if a conversion is needed.
Private functions are used when no outside functions or classes will call those functions.
Static functions are used when they do not read or write to a myclass, but are an integeral part of the concept of the class.
Constant functions can be used on const objects, and do not modify the class.
encapsulation means combining relevant data and functions. So it's irrelevant here.
If a function doesn't change member variables it is marked as const, but depending on the context it can still happily belong to a class instead of being forced to be a lonely free static function.
Personally (this can be debated) I believe that you should put together all relevant functions into a single class or AT THE VERY LEAST a namespace instead of leaving them all alone.
Though from java, from design pov this is a valid example: http://download.oracle.com/javase/1.5.0/docs/api/java/util/Arrays.html, http://download.oracle.com/javase/1.5.0/docs/api/java/util/Collections.html
I'm working on a sound library (with OpenAL), and taking inspiration from the interface provided by FMOD, you can see the interface at this link.
I've provided some concepts like: Sound, Channel and ChannelGroup, as you can see through FMOD interface, all of those classes have a private constructor and, for example, if you would create a Sound you mast use the function createSound() provided by the System class (the same if you would create a Channel or a ChannelGroup).
I'd like to provide a similar mechanism, but I don't understand how it work behind. For example, how can the function createSound() create a new istance of a Sound? The constructor is private and from the Sound interface there aren't any static methods or friendship. Are used some patterns?
EDIT: Just to make OP's question clear, s/he is not asking how to create a instance of class with private constructor, The question is in the link posted, how is instance of classes created which have private constructor and NO static methods or friend functions.
Thanks.
Hard to say without seeing the source code. Seems however that FMOD is 100% C with global variables and with a bad "OOP" C++ wrapper around it.
Given the absence of source code and a few of the bad tricks that are played in the .h files may be the code is compiled using a different header file and then just happens to work (even if it's clearly non-standard) with the compilers they are using.
My guess is that the real (unpublished) source code for the C++ wrapper is defining a static method or alternatively if everything is indeed just global then the object is not really even created and tricks are being played to fool C++ object system to think there is indeed an object. Apparently all dispatching is static so this (while not formally legal) can happen to work anyway with C++ implementations I know.
Whatever they did it's quite ugly and non-conforming from a C++ point of view.
They never create any instances! The factory function is right there in the header
/*
FMOD System factory functions.
*/
inline FMOD_RESULT System_Create(System **system)
{ return FMOD_System_Create((FMOD_SYSTEM **)system); }
The pointer you pass in to get a System object is immediately cast to a pointer to a C struct declared in the fmod.h header.
As it is a class without any data members who can tell the difference?
struct Foo {
enum Type {
ALPHA,
BETA_X,
BETA_Y
};
Type type () const;
static Foo alpha (int i) {return Foo (ALPHA, i);}
static Foo beta (int i) {return Foo (i<0 ? BETA_X : BETA_Y, i);}
private:
Foo (Type, int);
};
create_alpha could have been a free function declared friend but that's just polluting the namespace.
I'm afraid I can't access that link but another way could be a factory pattern. I'm guessing a bit, now.
It is the factory pattern - as their comment says.
/*
FMOD System factory functions.
*/
inline FMOD_RESULT System_Create(System **system) { return FMOD_System_Create((FMOD_SYSTEM **)system); }
It's difficult to say exactly what is happening as they don't publish the source for the FMOD_System_Create method.
The factory pattern is a mechanism for creating an object but the (sub)class produced depends on the parameters of the factory call. http://en.wikipedia.org/wiki/Factory_method_pattern
Can I create a function inside a class without defining it in the header file of that class?
Why don't you try and see?
[˙ʇ,uɐɔ noʎ 'oᴎ]
Update: Just to reflect on the comments below, with the emphasis of the C++ language on smart compiling, the compiler needs to know the size of the class (thus requiring declaration of all member data) and the class interface (thus requiring all functions and types declaration).
If you want the flexibility of adding functions to the class without the need to change the class header then consider using the pimpl idiom. This will, however, cost you the extra dereference for each call or use of the function or data you added. There are various common reasons for implementing the pimpl:
to reduce compilation time, as this allows you to change the class without changing all the compilation units that depend on it (#include it)
to reduce coupling between a class' dependents and some often-changing implementation details of the class.
as Noah Roberts mentioned below the pimpl can also solve exception safety issues.
No. However, you can mimic such:
struct X
{
void f();
X();
~X();
private:
struct impl;
impl * pimpl;
};
// X.cpp
struct X::impl
{
void f()
{
private_function();
...
}
void private_function() { ...access private variables... }
};
//todo: constructor/destructor...
void X::f() { pimpl->f(); }
Short answer: No, you can't.
However, if you're trying to inject a private function into the class that will only be used in that class's implementation, you can create a function in an anonymous namespace within that class's .cpp file that takes an object of that type by reference or pointer.
Note that you won't be able to muck with the passed objects internal state directly (since there's no way for the class to declare friendship with that anonymous function), but if the function just aggregates operations from the public interface of the class it should work just fine.
No, you can't. It wouldn't make much sense anyway. How should users of your class that include the header file know about those functions and use them?
I have no idea what You are trying to do, but I have a strange gut feeling, that Pointer To Implementation (pImpl) idiom might be helpful. If you want to add a public method in a cpp file and that method is not declared in the class definition in a header, You can't do that and it doesn't make sense.
I have two basic questions. The first one is about function in other classes. If I have a header file with a class in it and I want to use that function in another class I have created, do I always have to construct a class object to run a function in that class like:
someclass class; <----object construction
class.somefunction();
Is there a way just to call the function with the object construction?
And the second question is it okay to put multiple small classes in one header file?
Functions should only be member functions if they act on an object of the class. Functions that don't act on an object should just be plain global functions (or class static):
// Global function
void foo() { /* do something */ }
// Static function
class Foo
{
public:
static void foo() { /* do something */ }
};
For your second question, yes it's ok. Generally people stick to one class per file, but in my opinion there's nothing wrong with having a few small classes in a single file.
If your function is declared static then you don't need an object instance to call it.
class Foo
{
public:
static void Bar() {}
};
// ...later
Foo::Bar();
To answer your second question, yes it's sometimes ok. I've done that before with small utility structs that are related to each other. Usually I'm just being lazy and don't want to bother making separate files.
Is there a way just to call the function with the object construction?
Only if the function is declared static. (ok, that's a lie, its possible without constucting a object if you subvert the type system, but it's not a good idea)
And the second question is it okay to put multiple small classes in one header file?
Sure, it's done all of the time.
1 static as already mentioned
2 do what feels natural. Keep related classes together. One of the problems with JAva is its fanatical enforcement of one class per file
However - unforgivable sin is spreading the implementation of class a throughout the implementations of classes b c and d
Ie all of a class implementation should be in one .cpp file.
delcare the function as static.
Are you talking about inner classes? If thats the case, then its totally legit.