Здравствуйте, xzibit, Вы писали:
X>для чего нужны implisit explisit.
Может, тебе лучше обратиться в форум "Проблемы перевода"?
Здравствуйте, xzibit, Вы писали:
X>для чего нужны implisit explisit.
implicit (неявный), explicit (явный)
В контексте С++ это относится к одноаргументным конструкторам.
struct my_string
{
const char* str_;
my_string(const char* str) : str_(strdup(str)) {}
~my_string() { free(str_); }
.....
};
struct my_buffer
{
char* buf_;
explicit my_buffer(char* buf) : buf_(buf) {}
~my_buffer() { delete[] buf_; }
.....
};
void foo(const my_string& s);
void bar(const my_buffer& b);
int main()
{
foo("hello"); // неявное преобразование типа char[] -> my_string с использованием конструктора
bar("hello"); // конструктор явный, приводит к ошибке компиляции (а иначе был бы AV)
bar(my_buffer(new char[100])); // программист должен осознавать, что именно он пытается сделать
}
Вот так, вкратце.
Здравствуйте, xzibit, Вы писали:
X>для чего нужны implisit explisit.
ISO/IEC 14882:1998:
12.3.1 Conversion by constructor
1 A constructor declared without the function-specifier explicit that can be called with a single parameter
specifies a conversion from the type of its first parameter to the type of its class. Such a constructor is
called a converting constructor. [Example:
class X {
// ...
public:
X(int);
X(const char*, int =0);
};
void f(X arg)
{
X a = 1; // a = X(1)
X b = "Jessie"; // b = X("Jessie",0)
a = 2; // a = X(2)
f(3); // f(X(3))
}
—end example]
2 An explicit constructor constructs objects just like non-explicit constructors, but does so only where the direct-initialization syntax (8.5) or where casts (5.2.9, 5.4) are explicitly used. A default constructor may be an explicit constructor; such a constructor will be used to perform default-initialization (8.5). [Example:
class Z {
public:
explicit Z();
explicit Z(int);
// ...
};
Z a; // OK: default-initialization performed
Z a1 = 1; // error: no implicit conversion
Z a3 = Z(1); // OK: direct initialization syntax used
Z a2(1); // OK: direct initialization syntax used
Z* p = new Z(1); // OK: direct initialization syntax used
Z a4 = (Z)1; // OK: explicit cast used
Z a5 = static_cast<Z>(1); // OK: explicit cast used
—end example]
Если вопрос все же об explicit-конструкторах: одноаргументный конструктор без explicit может использоваться для неявного преобразования типа, explicit же запрещает это.
Вот у меня было такое:
struct Point
{
int x_, y_;
};
struct Tower
{
Point location_;
double height_;
/* not explicit */ Tower(Point location, double height = DEFAULT_HEIGHT);
};
double dist(Point p1, Point p2);
double dist(Tower t1, Tower t2)
{
return dist(t1.location(), t2.location()) + t1.height() + t2.height();
}
...
dist(somePoint, someTower); // oops!
При вызове somePoint неявно преобразовывается к типу Tower и происходят нехорошие вещи.
explicit можно не ставить тогда, когда неявное преобразование не меняет сути объекта. Например, запись Complex(double re = 0, double im = 0) вполне допустима, т. к. Complex(2) и 2 — одно и тоже. А вот std::vector<int>(3) и 3 — совсем разные вещи, поэтому этому конструктору без explicit не обойтись.