How to Make a Class Whose Constructor Looks Like the Constructor of a Built-In Class

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
call Date(…) is not equivalent to the
object creation expression new 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



Leave a reply



Submit