Is ok to have one constructor for each built in data types C++
The only reason you should make more than one constructor is if extra handling or conversion logic is required. For example:
#include <string>
#include <iostream>
class myClass
{
public:
unsigned long long int words;// public for ease of example
// will consume anything convertable to unsigned long long
myClass(unsigned long long int val) :
words(val)
{
}
// will consume anything convertable to std::string, and then convert
// the string to unsigned long long
myClass(std::string val) :
words(std::stoull(val))
{
}
};
int main()
{
std::cout << myClass{ 10 }.words << ": 10" << std::endl;
std::cout << myClass{ -10 }.words << ": -10 (Two's compliment wrap)" << std::endl;
std::cout << myClass{ 3.14 }.words << ": 3.14 (Truncated)" << std::endl;
std::cout << myClass{ "10" }.words << ": \"10\"" << std::endl;
std::cout << myClass{ "-10" }.words << ": \"-10\" (Two's compliment wrap)" << std::endl;
}
10 is converted easily. -10 and 3.14 are converted, but will generate warnings because the value will be damaged by the translation. "10" and "-10" will be accepted by the string
-parametered constructor, but "-10" will be mangled by std::stoull
. Additional logic, and probably use of strtoull
, will be required to handle this, if required.
custom constructors for built-in types in c++
Well, there is no constructor for a basic pointer - in the sense that there is no function implicitly called in order to initialise the pointer.
The closest you can come is to use a user-defined conversion operator function
class Entity
{
public:
operator int *();
};
Entity::operator int *()
{
// return something appropriate that is of type int *
}
// sample usage in a function somewhere
int *p = some_entity; // implicitly conversion that calls the operator int *()
int *another_p = static_cast<int *>(some_entity); // explicit conversion
int *yet_another_p = some_entity.operator int *();
There are variants of this, depending on what form of const
qualification is needed (e.g. if the operator function doesn't change the object it acts on, it should be const
and may be defined as operator const int *()
).
It is necessary to ensure that the pointer returned by the operator function is treated appropriately. If the user defined operator function returns a member of some_entity
, it cannot be used once some_entity
ceases to exist. Similarly, if it uses dynamic memory allocation (e.g. return the result of a new
expression) the caller must explicitly release that memory to avoid a memory leak.
Do built-in types have default constructors?
A constructor is a member function (constructors are fully specified in clause 12 of the C++ Standard, which covers special member functions like constructors and destructors).
A member function can only be defined for a class type (C++03 9.3/1 says "Functions declared in the definition of a class, excluding those declared with a friend specifier, are called member functions of that class").
So non-class types (including fundamental types, array types, reference types, pointer types, and enum types) do not have constructors.
I don't have a copy of The C++ Programming Language to read the context of the quote that "Built-in types also have default constructors," but I would guess that Stroustrup is either using the term "constructor" in a loose, non-technical sense, or the meaning of the term or the way in which it is used in the Standard changed between when the book was published and when the language was standardized. I'd guess the former is far more likely than the latter.
Ruby: BigDecimal: a class and a method at the same time?
BigDecimal
is a class, but it is also a method defined in the Kernel
module.
Methods that are defined in the Kernel doesn't have to have a receiver to be called, as the Kernel
module is mixed with the Object
class.
From the docs: The Kernel module is included by class Object, so its methods are available in every Ruby object.
Ruby knows Array.new
and Array(1)
are different things because constants (classes and modules are constants) do not receive arguments.
class Abc
end
def Abc
puts 'Method called'
end
Abc()
#=> Method called
Abc
#=> Abc (Class)
As Matz once said:
I'm trying to make Ruby natural, not simple. Ruby is simple in appearance, but is very complex inside, just like our human body.
Built-in datatypes versus User defined datatypes in C++
While initializing a built-in datatype variable, the variable also HAS to be "built from dust" . So, are there also constructors for built in types?
Per request, I am rebuilding my answer from dust.
I'm not particularly fond of that "Constructors build objects from dust" phrase. It is a bit misleading.
An object, be it a primitive type, a pointer, or a instance of a big class, occupies a certain known amount of memory. That memory must somehow be set aside for the object. In some circumstances, that set-aside memory is initialized. That initialization is what constructors do. They do not set aside (or allocate) the memory needed to store the object. That step is performed before the constructor is called.
There are times when a variable does not have to be initialized. For example,
int some_function (int some argument) {
int index;
...
}
Note that index
was not assigned a value. On entry to some_function
, a chunk of memory is set aside for the variable index
. This memory already exists somewhere; it is just set aside, or allocated. Since the memory already exists somewhere, each bit will have some pre-existing value. If a variable is not initialized, it will have an initial value. The initial value of the variable index
might be 42, or 1404197501, or something entirely different.
Some languages provide a default initialization in case the programmer did not specify one. (C and C++ do not.) Sometimes there is nothing wrong with not initializing a variable to a known value. The very next statement might be an assignment statement, for example. The upside of providing a default initialization is that failing to initialize variables is a typical programming mistake. The downside is that this initialization has a cost, albeit typically tiny. That tiny cost can be significant when it occurs in a time-critical, multiply-nested loop. Not providing a default initial value fits the C and C++ philosophy of not providing something the programmer did not ask for.
Some variables, even non-class variables, absolutely do need to be given an initial value. For example, there is no way to assign a value to a variable that is of a reference type except in the declaration statement. The same goes for variables that are declared to be constant.
Some classes have hidden data that absolutely do need to be initialized. Some classes have const
or reference data members that absolutely do need to be initialized. These classes need to be initialized, or constructed. Not all classes do need to be initialized. A class or structure that doesn't have any virtual functions, doesn't have an explicitly-provided constructor or destructor, and whose member data are all primitive data types, is called plain old data, or POD. POD classes do not need to be constructed.
Bottom line:
- An object, whether it is a primitive type or an instance of a very complex class, is not "built from dust". Dust is, after all, very harmful to computers. They are built from bits.
- Setting aside, or allocating, memory for some object and initializing that set-aside memory are two different things.
- The memory need to store an object is allocated, not created. The memory already exists. Because that memory already exists, the bits that comprise the object will have some pre-existing values. You should of course never rely on those preexisting values, but they are there.
- The reason for initializing variables, or data members, is to give them a reliable, known value. Sometimes that initialization is just a waste of CPU time. If you didn't ask the compiler to provide such a value, C and C++ assume the omission is intentional.
- The constructor for some object does not allocate the memory needed to store the object itself. That step has already been done by the time the constructor is called. What a constructor does do is to initialize that already allocated memory.
The initial response:
A variable of a primitive type does not have to be "built from dust". The memory to store the variable needs to be allocated, but the variable can be left uninitialized. A constructor does not build the object from dust. A constructor does not allocate the memory needed to store the to-be constructed object. That memory has already been allocated by the time the constructor is called. (A constructor might initialize some pointer data member to memory allocated by the constructor, but the bits occupied by that pointer must already exist.)
Some objects such as primitive types and POD classes do not necessarily need to be initialized. Declare a non-static primitive type variable without an initial value and that variable will be uninitialized. The same goes for POD classes. Suppose you know you are going to assign a value to some variable before the value of the variable is accessed. Do you need to provide an initial value? No.
Some languages do give an initial value to every variable. C and C++ do not. If you didn't ask for an initial value, C and C++ are not going to force an initial value on the variable. That initialization has a cost, typically tiny, but it exists.
java access Integer constructor through reflection
The problem here is the distinction between:
Integer.class
int.class
The constructor for Integer takes an int
parameter, not an Integer
.
To get your magic method to work, you would need to do a special check of the type, and if it's a wrapper class, actually look for a constructor whose parameter is the corresponding primative type.
AFAIK there's no built in way to get the primatove class from the wrapper class - you could use a map and populate it with the mappings:
private static final Map<Class<?>, Class<?>> MAP = new HashMap<>() {{
put(Integer.class, int.class);
put(Long.class, long.class);
// etc
}};
Then in your method:
Class<?> type = MAP.containsKey(var.getClass()) ? MAP.get(var.getClass()) : var.getClass();
return (V) var.getClass().getConstructor(type).newInstance(var);
It's OK to pass the int
as an Integer
in the parameter value - that at least gets auto unboxed.
Instantiating a JavaScript object by calling prototype.constructor.apply
I've done more investigation of my own and came up with the conclusion that this is an impossible feat, due to how the Date class is implemented.
I've inspected the SpiderMonkey source code to see how Date was implemented. I think it all boils down to the following few lines:
static JSBool
Date(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
jsdouble *date;
JSString *str;
jsdouble d;
/* Date called as function. */
if (!(cx->fp->flags & JSFRAME_CONSTRUCTING)) {
int64 us, ms, us2ms;
jsdouble msec_time;
/* NSPR 2.0 docs say 'We do not support PRMJ_NowMS and PRMJ_NowS',
* so compute ms from PRMJ_Now.
*/
us = PRMJ_Now();
JSLL_UI2L(us2ms, PRMJ_USEC_PER_MSEC);
JSLL_DIV(ms, us, us2ms);
JSLL_L2D(msec_time, ms);
return date_format(cx, msec_time, FORMATSPEC_FULL, rval);
}
/* Date called as constructor. */
// ... (from here on it checks the arg count to decide how to create the date)
When Date is used as a function (either as Date()
or Date.prototype.constructor()
, which are exactly the same thing), it defaults to returning the current time as a string in the locale format. This is regardless of any arguments that are passed in:
alert(Date()); // Returns "Thu Oct 09 2008 23:15:54 ..."
alert(typeof Date()); // Returns "string"
alert(Date(42)); // Same thing, "Thu Oct 09 2008 23:15:54 ..."
alert(Date(2008, 10, 10)); // Ditto
alert(Date(null)); // Just doesn't care
I don't think there's anything that can be done at the JS level to circumvent this. And this is probably the end of my pursuit in this topic.
I've also noticed something interesting:
/* Set the value of the Date.prototype date to NaN */
proto_date = date_constructor(cx, proto);
if (!proto_date)
return NULL;
*proto_date = *cx->runtime->jsNaN;
Date.prototype
is a Date instance with the internal value of NaN
and therefore,
alert(Date.prototype); // Always returns "Invalid Date"
// on Firefox, Opera, Safari, Chrome
// but not Internet Explorer
IE doesn't disappoint us. It does things a bit differently and probably sets the internal value to -1
so that Date.prototype always returns a date slightly before epoch.
Update
I've finally dug into ECMA-262 itself and it turns out, what I'm trying to achieve (with the Date object) is -- by definition -- not possible:
15.9.2 The Date Constructor Called as a Function
When Date is called as a
function rather than as a constructor,
it returns a string representing the
current time (UTC).NOTE The function
callDate(…)
is not equivalent to the
object creation expressionnew Date(…)
with the same arguments.15.9.2.1 Date ( [ year [, month [, date [, hours [, minutes [, seconds [,
ms ] ] ] ] ] ] ] )All of the
arguments are optional; any arguments
supplied are accepted but are
completely ignored. A string is
created and returned as if by the
expression(new Date()).toString()
.
How do you indicate that a class will have a particular static method?
You can't require implementing classes have a static method. I suggest you not reuse a common builtin class name like Vector
as it leads to confusion.
If you have a non-trivial requirement for construction I suggest you use a Factory method to create your instance. In your case you can specify that E
have a method zero()
even though it is not static. The problem is you have to pass the class, or an instance of that class as an argument. A method/constructor doesn't know what generics you used when you called it and they have to be parameters.
Related Topics
Does Ruby Have Any Number Formatting Classes
How to Include Blank Field in Select_Tag
Check to See If an Array Is Already Sorted
Rails 4.1 Activerecord::Relation Is No More Like Array
Inherit Class-Level Instance Variables in Ruby
How to Extract a Single Character (As a String) from a Larger String in Ruby
How to Print Stdout Immediately
How Do Version Numbers Work for Mri Ruby
Rspec: Should Be (This or That)
Unpermitted Parameters for Dynamic Forms in Rails 4
Simplest Way to Send Raw Byte-Arrays Using Ruby's Tcpsocket-Class
Stop Loading Page Watir-Webdriver
Ruby.Metaprogramming. Class_Eval
Ruby Pipes: How to Tie the Output of Two Subprocesses Together
How to Inspect What Is the Default Value for Optional Parameter in Ruby's Method
How to Remove Duplicates in a Hash in Ruby on Rails