Why Does C++ Not Have a Const Constructor

Why does C++ not have a const constructor?

It would not be a const method itself

If this constructor were not a const method itself, then the internal pointers and such would also not be const. Therefore, it could not set const values into those non-const members.

The only way to make it work syntactically is for this constructor to require member initialization for all non-mutable members. Essentially, any member not declared mutable would be implicitly declared const when using this constructor. Which is equivalent to making the constructor a const method; only initializers could initialize members. The constructor's body could do nothing with non-mutable members, because those members would be const at that point.

What you are asking for is syntactically dubious. You're essentially trying to hoodwink the API, storing constant data in an object that is designed for mutable data (which is why you didn't declare the member pointer to be const). If you want different behavior for an object, you need to declare the object to have that specific behavior.

Constructor for `const` object

How to properly declare my class constructors so that it can handle const and non-const object creation?

The object isn't const during construction, or the constructor wouldn't be able to initialize the object (since all data members would be const).

So, constructors can't be const-qualified and you can't have a constructor overload used for const objects.

Now, you can overload on the argument, but your data member always has type char * during construction, although it's qualified to char * const (not const char *) when used in a const-qualified instance of test.

Options are:

  1. overload constructor on argument type, and store a char * always. If you're passed a const char * you have to copy it (and you're responsible for knowing that you own and must deallocate this memory)

    In this scheme, you rely on keeping the pointer private and using const-qualified accessors to stop the contents of the pointer being changed via a const-qualified object.

    Again, you need to do this manually because char * const is a different type than const char *, because constness of the pointed-to type isn't related to constness of the pointer: having a const instance of your class just stops you mutating the pointer, not the characters it points to.

  2. overload constructor and store a const char * always. This avoids copying but obviously doesn't work if you sometimes need to change the pointed-to characters

  3. just write different mutable-string and immutable-string classes

If it helps, consider this:

template <typename T> struct test {
T* p_;
test(T *p) : p_(p) {}
};
template <typename T> test<T> mktest(T *p) { return {p}; }

and note that

const char *ccp = "immutable characters in a string literal";
char *cp = strdup(ccp);
auto a = mktest(ccp);
auto b = mktest(cp);

gives a the type test<const char>, and b the type test<char> and that these types are not the same, are not convertible, and are no more closely related in the language than to test<T> for any other type T.

cant define a const constructor for a class with non final fields Flutter

Replace const CustomButton({Key key, this.buttonType}) with const ContainerButton({Key key, this.buttonType}) And you have to place it outside the statefull class

Here is the final code :

class ContainerButton extends StatefulWidget {
final ButtonType buttonType;
const ContainerButton({Key key, this.buttonType}) : super(key: key);
@override
ContainerButtonState createState() => ContainerButtonState();
}

class ContainerButtonState extends State<ContainerButton> {

@override
Widget build(BuildContext context) {
return Container(
padding: EdgeInsets.all(21),
color: Color(0xfff4f5f9),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Flexible(
child: CustomButton(buttonType: ButtonType.download),
),
Flexible(
child: CustomButton(buttonType: ButtonType.share),
),
Flexible(
child: CustomButton(buttonType: ButtonType.problem),
),
],
),
);
}
}

Is there such a thing as a const constructor?

Your code is not standard compliant, there is no such thing. However, starting with C++11, you can have constexpr constructors, so your object is constructed at compile time and can further be used in constexpr expressions.

Although I am not using it, MSVS is not the best compiler in terms of standard-compliance, at least that's what I realized from various questions on this site.

Const and non-const c++ constructor

No, not the way you are wanting to use it. The only way to have different behavior at compile time is to have different types. However, you can make that fairly easy to use:

#include <stdio.h>

template <typename T>
class SometimesConst
{
public:
SometimesConst(T* buffer) : buffer(buffer) { }
T* get() { return buffer; }
void increment() { ++counter; }
private:
T *buffer;
int counter;
};

typedef SometimesConst<const int> IsConst;
typedef SometimesConst<int> IsNotConst;

void function(int * n, const int * c)
{
IsNotConst wn(n);
IsConst wc(c);

// Reading the value is always allowed
printf("%d %d", wn.get()[0], wc.get()[0]);

// Can increment either object's counter
wn.increment();
wc.increment();

// Can set non-const pointer
wn.get()[0] = 5;

// Should generate a compiler error
wc.get()[0] = 5;
}

Why does gcc allow a const object without a user-declared default constructor but not clang?

The spec currently requires user-provided default constructors but it appears that GCC is implementing a change based on DR 253 which says that if all sub-objects would be initialized without a user provided default constructor then a user-provided default constructor is not required.

This change is only draft status, has not been accepted yet and is not part of the standard. So I think think this is behavior intended by GCC developers but I'm not sure if this is a conforming extension though.

Here's a change to the first example which causes GCC to produce an error:

class A {
public:
void f() {}

int i;
};

int main()
{
A a; // OK
const A b; // ERROR

a.f();
return 0;
}

Note that gcc downgrades the error to a warning with the -fpermissive flag.

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=42844

Initialize const variable in constructor after changing it

You can pass the parameter to a function, and let the function return the modified string.

class Client {
private:
const std::string email;
static std::string validateEmail(std::string email) {
// ...
return modifiedEmail;
}

public:
Client::Client(std::string emailAddress) : email{validateEmail(std::move(emailAddress))}
{

}
};


Related Topics



Leave a reply



Submit