So normally I wouldn't ask a question like this because it seems like it could be opinion based or start some sort of verbal war on coding practices, but I think there might be a technical reason here that I don't understand.
I was looking over the code in the header files for vcpkg (a library packing manager that Microsoft is creating and is "new" code) because reading code generally is a good way to learn things you didn't know.
The first thing I noticed was the use of using rather than typedef.
Snippet from 'https://github.com/microsoft/vcpkg/blob/master/toolsrc/include/vcpkg/parse.h'
template<class P>
using ParseExpected = ExpectedT<std::unique_ptr<P>, std::unique_ptr<ParseControlErrorInfo>>;
I haven't personally used using this way before and an answer from: What is the difference between 'typedef' and 'using' in C++11?. Essentially, using is the new way to do it, and the benefit is that it can use templates. So Microsoft had a good reason to use using instead of typedef.
Looking at 'https://github.com/microsoft/vcpkg/blob/master/toolsrc/include/vcpkg/commands.h' I noticed that they did not use any classes. Instead it was only namespaces with a function or so in them. ie:
namespace vcpkg::Commands
{
namespace BuildExternal
{
void perform_and_exit(const VcpkgCmdArguments& args, const VcpkgPaths& paths, const Triplet& default_triplet);
}
}
I'm guessing that part of this is that the calling syntax looks essentially just like a static member function in a class, so the code performs the same but maybe saves some overhead by being a namespace instead of a class. (If anyone has any ideas on this too that would be great.)
Now the main point of all this. Why is Microsoft using structs instead of classes in their namespaces?
Snippet from 'https://github.com/microsoft/vcpkg/blob/master/toolsrc/include/vcpkg/parse.h':
namespace vcpkg::Parse
{
/* ... Code I'm excluding for brevity ... */
struct ParagraphParser
{
ParagraphParser(RawParagraph&& fields) : fields(std::move(fields)) {}
void required_field(const std::string& fieldname, std::string& out);
std::string optional_field(const std::string& fieldname) const;
std::unique_ptr<ParseControlErrorInfo> error_info(const std::string& name) const;
private:
RawParagraph&& fields;
std::vector<std::string> missing_fields;
};
}
Searching stackoverflow, I found an old question: Why Microsoft uses a struct for directX library instead of a class?
Which the answers were essentially, you don't have to declare things as public as default and a comment way at the bottom saying that it was old code.
If vcpkg was old code I would be completely satisfied, however, this is new code. Is it just some style they have that is a carry over (but using vs typedef isn't)? Or is it to save a line of code (public:)? Or is there some sort of overhead benefit? Or some other thing I haven't considered at all?
The only differences between struct and class are:
the default member access (public vs private) and
the default inheritance if you inherit from the type (public inheritance vs private inheritance).
The end result of 1 will be the same once the author has finished adding public:/private: to the type. 2 you can easily control yourself by being explicit when you inherit, rather than rely on the default. It's hardly a big deal and doesn't really matter.
As to why Microsoft uses struct rather than class in their code, you will have to ask some Microsoft people.
Regarding the free functions vs static functions, I don't think there is any overhead in this with classes (I haven't measured this at all, I would just think that most compiler would recognize that the class is basically just a namespace for the function). The thing is just: You don't need a class.
Using a class with only static functions is basically abusing the class as a namespace. So if you are only doing that, then be explicit about it and just use a namespace. Having a class there would only be confusing since you would think that maybe there could be some state here and just see that there is non when you see that the function in the class is static.
This is especially relevant if this is used a bit wrongly. Imagine someone instantiates a class A a with static member function f to call a.f(). It is no problem regarding performance, since the construction is a no-op and it will pretty much be equivalent to A::f(). But for the reader it seems like there is some kind of state involved and that is just confusing.
Regarding the other two: using is just superior to typedef throught being able to use templates and is (IMO) better readable. The struct vs class issue is just something over what has the better defaults, its not a big difference, but most often, what you want is what a struct does, so there is no reason to use a class.
To be (more) compatible with C
To avoid making everything public by using the public: keyword, since that all COM objects for example have only public member functions.
Related
I am designing a SDK written in C++.
I have a question: could or should I totally hide the internal class in my public C++ header file?
The code snippets are like the following (in the header file MyPublicClass.h):
namespace PublicNamespace
{
namespace InternalNamespace
{
class MyInternalClass;
}
class MyPublicClass
{
public:
void SomeMemberFunc();
...
private:
std::shared_ptr<InternalNamespace::MyInternalClass> mImpl;
}
}
Per the C++ PImpl design pattern (and also many other materials from Google), it is OK to put the InternalNamespace::MyInternalClass into the public header.
My thought is: it looks unnecessary to let the external users know the internal namespace InternalNamespace, and also the class MyInternalClass. So I want to use void to replace the type InternalNamespace::MyInternalClass.
That's to say, for my case, I use std::shared_ptr<void> as the type of the data member mImpl, and in the .cpp file, use std::static_pointer_cast<InternalNamespace::MyInternalClass>(mImpl) to convert it to the actual class.
(Yeah, I know there is a little cost with this conversion but please ignore it).
Is this design correct or proper? Thanks all.
Don't use void or void * unless there is absolutely no alternative -- using void-pointers prevents the compiler from catching mistakes at compile-time, and leads to pain and suffering.
Using a clearly-labelled InternalNamespace should be good enough (assuming the programmers using your API aren't deliberately looking for trouble -- and if they are, there are plenty of other ways for them to find it anyway), although if you wanted to hide MyInternalClass entirely from calling code, you could instead make it an inner-class of MyPublicClass, i.e. something like this:
namespace PublicNamespace
{
class MyPublicClass
{
public:
void SomeMemberFunc();
...
private:
class MyInternalClass
{
[...]
};
std::shared_ptr<MyInternalClass> mImpl;
}
}
Since it's declared in the private section of MyPublicClass, no calling code outside of MyPublicClass would be able to access it at all.
I was wondering if it would be possible to do the following:
template <typename T>
namespace basic_foo {
struct str {
T value;
};
}
basic_foo<char>::str s1;
namespace foo = basic_foo<char>;
foo::str s2;
Is it possible to do this in any c++ compiler?
Is there work being done to implement this?
I think that it would be a great addition to the language.
Thanks in advance.
No, you cannot define a namespace template. You can, however, achieve almost exactly what you want (with only slightly different syntax), by making basic_foo a class template:
template <typename T>
struct basic_foo {
struct str {
T value;
};
};
basic_foo<char>::str s1;
typedef basic_foo<char> foo;
foo::str s2;
No, but you can use templated struct:
template<typename T>
struct basic_foo
{
struct str
{
T value;
};
};
typedef basic_foo<char> foo;
foo::str s1;
You could also use class instead of struct, but you would have to remember about public: in such case.
No. It`s impossible, namespace template is unreal, but you can make class template.
The other answers explain how to do what it looks like you might want. But it sounds like you have a different idea of what a namespace is for than what it really is designed for.
namespace solves the problem of two unrelated C++ code bases being able to communicate with each other. C doesn't have namespaces and is much more verbose as a result. Try using a 3rd party library such as openssl or oauth in C. You'll find a lot of function calls like this:
openssl_create
openssl_connect
and so on. And this is really, really important. Because chances are I want to write a function called connect. And so does the author of the ZMQ library I used. And so forth. And it's a major, major pain to have two functions with the same name trying to be called in the same place...
namespace is purely a software engineering construct, not a programming one. It lets the prefix openssl_ simply become the namespace so code like the above can intermingle more freely. Why don't namespaces conflict? This is where software engineering becomes even more human and social, as essentially the global programming community must make sure this doesn't happen. Generally outer namespaces are usually companies; I would guess all Google internal code is in namespace Google. Java solves this by promoting the convention of naming package (like namespace) by the internet domain name, which is presumably a real-world entity that can't conflict, e.g. Google code should live in package com.google...
I should also note that within an organization namespaces are used at the application, or product, or team level - e.g. Google Drive probably has a function "upload" somewhere as does Google Mail, and those teams might generally not talk to each other... but still need to write intermingling code.
That's what namespaces do. Nothing more, nothing less.
i saw that some times in c++ applications using only namespace declarations with header and source file like this :
#ifndef _UT_
#define _UT_
#include <string>
#include <windows.h>
namespace UT
{
void setRootPath(char* program_path, char* file_path);
char * ConvertStringToCharP(std::string str);
};
#endif
//and then in UT.cpp
#include "UT.h"
namespace UT
{
char * ConvertStringToCharP(std::string str)
{
char * writable = new char[str.size() + 1];
std::copy(str.begin(), str.end(), writable);
writable[str.size()] = '\0';
return writable;
}
void setRootPath(char* program_path, char* file_path)
{
//...
}
}
is it better then defining classic class with static methods?
or just simple class ?
dose this method has something better for the compiler linker ?
the methods in this namespace are called allot of times .
By shear coincidence I happen to read this answer for a slightly different question in Stack Overflow. In that the user rhalbersma had given a nice link to a Dr Dobb's article where the author Scott Meyers explains how methods implemented outside the class (non-friend methods), but inside the same namespace actually improve encapsulation. For me it was a good learning for today. Hope this helps you as well.
Performance-wise, there's no difference between having static class members and free functions in a namespace. It's a matter of logic though. Are your functions related to the class or not?
A good question to ask yourself - are you creating the static member functions inside the class just for better organization (or just so you can group them together)? If the answer is yes, you should probably use a namespace.
You put a method outside all classes when the method's meaning is independent of a class. Static classes in other languages (Java, C#) are a way to compensate for inability to put methods outside classes. Since C++ provides this ability out of the box through namespaces, the use of an additional "static class" would be counterintuitive to the readers of your code.
The primary reasons for using a static class member function is a logical and conceptual relation to the class and its members.
Another reason may be to enable template partial specialisation, which is not allowed for function templates, but for classes.
Otherwise, use a standalone function (defined in an appropriate namespace).
There's no absolute rule, but in general, unless the functions show a
very large degree of coherence, and you want to close the "namespace"
for some reason, so clients can't add functions to it, using namespace
is generally preferable to using class. Unless, of course, the intent
is to make them available to templates: you can instantiate a template
on a class, but not on a namespace. (This technique is often called
"traits"; a class with no non-static members is called a traits class.)
Even if you do use namespaces, you should define the functions:
void UT::setRootPath( char const* programPath, char const* filePath)
{
// ...
}
char* UT::convertStringToCharP( std::string const& str )
{
// ...
}
This way, any typos in the signature of the function will be detected by
the compiler.
By default you should always try to minimise the methods on a class. If you can implement functionality in terms of the class rather than within a class you should. In other words if you can achieve the desired functionality through using the already published public interface then you should. This vastly reduces the dependency of your code on implementation details.
So if you can then implement it outside of the class in an appropriate namespace that naturally seems related to the class.
EDIT: It appears that the OP is really asking about whether to implement a namespace or a static class as a holder object for utility/related functions. In my opinion namespaces are the correct way to do this, because that is what they are there for. A class is not necessary.
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
I'm using the Boost Parameter tutorial to create a named-parameter constructor for a playing card generator. The tutorial says to put the ArgumentPack into a base class, but I want to modify variables in the card generator class. I've thought about doing this:
class CGconstructor_base {
public:
template<class ArgumentPack>
CGconstructor_base(ArgumentPack const& args);/*tutorial says to put code
in this function */
friend CardGenerator;//so it can modify the variables of CardGenerator
}
class CardGenerator:public CGconstructor_base;
Is this legal or is there a better way to manipulate the private variables in CardGenerator and use Boost Parameter library?
OS: Windows XP Pro, Compilier: Visual C++ 2008 Express,Boost: 1.39.0
I think we need some cleanup.
the friend declaration seems ill-placed, from the comment you want CGconstructor_base to be able to access CardGenerator attributes: if this is so, then the friend declaration goes into CardGenerator (I say who I consider as my friends, you do not declare yourself as being someone I consider a friend).
Why do you need friend anyway ? It would be much better if as in the tutorial you used a structure and then stuffed the attributes into CGconstructor_base. This way you will be able to access them from CardGenerator naturally without this supplementary line. When you can do without the 'friend' keyword you should (usual caveat: if doing so does not increase the cost too much).
you want PRIVATE inheritance here, this is a detail implementation. Only use public inheritance (or protected even) when OTHER classes/methods will need to know use you 'as-a' base.
In a nutshell:
struct CGconstructor_base {
template<class ArgumentPack>
CGconstructor_base(ArgumentPack const& args);/*tutorial says to put code
in this function */
cg_type1 cg_attr1;
cg_type2 cg_attr2;
}; // don't forget this
class CardGenerator:private CGconstructor_base {};
I do wonder why 'inheritance' has been chosen by boost instead of (I think) cleaner composition. It is so much easier to abuse inheritance (and require Multiple-Inheritance)... I suppose it is worth a subject of its own though.