This is likely a basic question, but I haven't seen this done before and I haven't found a reference that talks about it:
What is going on in the following code:
using HandlerType = std::function<bool()>;
class SpecificAction : public Action<HandlerType>
{
public:
using Action::Action;
};
Specifically, what is the reason for the 'using Action::Action'? Action is a class template with a bunch of methods defined for it, but this is the entire declaration for SpecificAction.
When you are defining a class SpecificAction deriving from Action, everything in Action is added to SpecificAction, except the constructors. This syntax is a way to tell the compiler that you want to use the constructor from Action as a constructor for SpecificAction.
The reason constructor are not added by default to the derived class is that the derived class is likely to add some more data members which will not be initialized by the base constructor. Using this syntax you're telling the compiler that it's ok, you know what you're doing.
Related
Here is a base class:
class Base
{
public:
int foo;
// ...
};
This class is declared in a header file that I cannot change because I don't have the rights to do so.
Here is a derived class:
class Derived : public Base
{
public:
// provide alias to Base::foo
// ...
};
Is there a way I can provide an alternate name that refers to Base::foo inside class Derived without using pointers or references?
In other words, is there any way to provide an alias without adding any extra class members to Derived?
Also, if conditional compilation directives can be avoided, that would be ideal.
No, there is no renaming feature (though there was some work done on such a feature in the early days but it was dropped).
There's no way to do what you want other than adding the desired name as a member to Derived, and forwarding it to the base class function. Note however that this can be inline and should be absorbed by the compiler so it won't hurt performance.
I have two classes, one has permitted making the only explicitly declared constructor, the no arguments one, private. I recently added another class but am getting compile-time errors due to having made the no argument constructor private. The only difference is the first had a public static factory method while the latter has a non-static constructor which takes an argument.
Thanks, hope this makes some sense.
Okay, I give you some code:
This doesn't compile:
class GridElem {
public:
GridElem(const char _idata);
~GridElem();
private:
GridElem();
}
This does compile:
class GridElem {
public:
GridElem(const char _idata);
~GridElem();
GridElem();
}
This does compile:
class MyClass {
public:
~MyClass();
private:
MyClass();
Not a complete example, sorry, but I believe this shows where the anomally arises, perhaps from extending cocos2d::Layer?
EDIT
Alright I found the call that is doing this (eclipse couldn't find it :()
in header
GridElem myGrid[15][15];
in cpp file
MyClass::MyClass() : myGrid{0} {}
I only recently changed it from a smaller grid and giving each element explicitly (because it was still just 0 for want of more information), I think this must now expand to parameterless c'tor. I completely forgot that, sorry, but it wasn't 100% obvious mistake.
You can always make the default constructor private (or not have a default constructor at all).
What you can't do is use a private default constructor from outside the class (or its friends).
You haven't provided enough context to know for sure, but I suspect your problem is that something else in your code is trying to default construct a GridElem, so it needs to be public.
The only difference is the first had a public static factory method while the latter has a non-static constructor which takes an argument.
If MyScene has a factory method then that's a member and can call the private default constructor. There's no "anomaly", you've just said that both types can only be default constructed by their own member functions (and friends), but only one of them has a member function to actually do that.
making default constructor private usually means you want all
creation to go through a factory. So use said factory, or make it public
I have a library given to me where I am supposed to subclass one of its struct for use in my own app. When I do this, it works fine. However, when I change my subclass definition to class instead of struct (and I make sure to public: before everything inside), the compiler (Visual Studio compiler 10) gives me this odd error:
typecast: conversion exists but is inaccessible
The line on which this error occurs looks like this:
LibraryNameSpace::Client c(config_options, &mySublassObject);
I don't understand why a simple change from struct to class creates this error; any compiler-added default constructors would apply to either struct or class, including conversion constructors (if that's the issue here).
Is it perhaps because creating a class subclass from a struct base class is not a good idea?
Members of a 'struct' are public by default, whereas members of a 'class' are private by default. If you do not specify public/private, all members in the 'struct' become private when you change it to 'class'.
Also did you inherit by private or public?
class Subclass : public SuperClass {
public:
// ...
};
I'm quite new to C++, but have general knowledge of other languages. Lately I've seen some tutorials about C++, and I have sometimes seen classes that do not have their own constructor, not even className();. This might exist in the other languages as well, but I've never seen it before. I don't think I've seen them in use before either, so my question is: what are they for? And what are they? I tried googling this, but I don't know the name for it.. 'constructorless class' didn't give me much.
Without a constructor, is it possible to instantiate it? Or is it more of a static thing? If I have a class that contains an integer, but has no constructor, could I go int i = myClass.int; or something like that? How do you access a constructorless class?
If you don't explicitly declare a constructor, then the compiler supplies a zero-argument constructor for you.*
So this code:
class Foo {
};
is the same as this code:
class Foo {
public:
Foo() {};
};
* Except in cases where this wouldn't work, e.g. the class contains reference or const members that need to be initialized, or derives from a superclass that doesn't have a default constructor.
If you do not specify a constructor explicitly compiler generates default constructors for you (constructor without arguments and copy constructor). So there is no such thing as constructorless class. You can make your constructor inaccessible to control when and how instances of your class created but that's a different story.
A class without a constructor is a good model for implementing an interface.
Many interfaces consist of methods and no data members, so there is nothing to construct.
class Field_Interface
{
public:
// Every field has a name.
virtual const std::string& get_field_name(void) const = 0;
// Every field must be able to return its value as a string
virtual std::string get_value_as_string(void) const = 0;
};
The above class is know as an abstract class. It is not meant to have any function, but to define an interface.
Is there a way to explicitly declare a base class as abstract in C++?
I know that I can create a pure virtual function in the class which will implicitly declare a class as abstract. However, I don't want to have to create a dummy function just to define in in derived classes.
I could also make the constructor protected, which would prevent the instantiation of the object, but that doesn't actually mark the class as abstract.
So, is there a way to do this? (I am using C++11, if that added a way to do this, but I didn't find anything that looked right)
You can make the destructor pure-virtual. Since you always need a destructor, there's no additional mental cost:
struct Foo
{
virtual ~Foo() = 0;
};
inline Foo::~Foo() { }
(You do of course need an implementation of the destructor, so you have to provide one out-of-line.)
You can still make the destructor protected, which is good practice following the "make non-leaf classes abstract" rule.
Example:
struct Bar : Foo { };
// Foo f; // Error, Foo is abstract
Bar b; // OK
I like Kerrek's answer. That way the class cannot be instantiated and therefore is abstract.
However, it still isn't obviously clear that the class is abstract unless you scan through the entire declaration of the class and see that the destructor is virtual.
Another idea I had is you could create a pre-processor definition for the word "abstract" using #define. This way you could do something like the following:
abstract struct Foo {};
which would be no different than
struct Foo {};
The problem I see with this is that this doesn't force the class to be abstract, so you could use a macro to also declare the virtual destructor. Something like:
#define ABSTRACT_CLASS(class_name) \
class class_name { \
virtual ~class_name() = 0; //
And then use it like so:
ABSTRACT_CLASS(Foo) {
// class declaration
};
Which would be turned into:
class foo {
virtual ~class_name() = 0; // {
// class declaration
};
Disclaimer: My macro might be slightly off. I'm not sure if it'll actually paste class_name with the ~ and the () touching the variable name. Also, I'm not sure if I'd do this myself, it's not the most beautiful solution, especially commenting out the brace since that wouldn't work if you put it on the next line. But you asked how you could mark something as abstract and I gave it to you!
Is there a way to explicitly declare a base class as abstract in C++?
No, there is not. A class is abstract only if it has at least one abstract method declared in it. If you do not want your base class to be instantiated directly, then a protected constructor is a good choice.