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:
overload constructor on argument type, and store a
char *
always. If you're passed aconst 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 thanconst 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.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 charactersjust 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
Do You (Really) Write Exception Safe Code
Insert VS Emplace VS Operator[] in C++ Map
How to See the Assembly Code for a C++ Program
Can the Use of C++11's 'Auto' Improve Performance
Std::Auto_Ptr to Std::Unique_Ptr
What Would Be C++ Limitations Compared C Language
How Boost::Function and Boost::Bind Work
Pimpl Idiom VS Pure Virtual Class Interface
Passing Shared Pointers as Arguments
In C++, Is It Still Bad Practice to Return a Vector from a Function
Super High Performance C/C++ Hash Map (Table, Dictionary)
Why Do We Actually Need Private or Protected Inheritance in C++
How to Find Where an Exception Was Thrown in C++
Rvalue to Lvalue Conversion Visual Studio
Why Sizeof(Int) Is Not Greater Than -1