Nicolai M. Josuttis的C++标准库声明:
两者之间存在细微差别
X x;
Y y(x) //explicit conversion
Run Code Online (Sandbox Code Playgroud)
和
X x;
Y y = x; //implicit conversion
Run Code Online (Sandbox Code Playgroud)
接下来说:"前者通过使用类型X的显式转换创建Y类型的新对象,而后者通过使用隐式转换创建类型为Y的新对象."
我猜对于显式与隐式转换的概念我有点困惑.在这两种情况下,你都使用X并将其推入Y本身 - 一个使用Y的构造函数,一个使用赋值运算符.
在这两种情况下如何处理转换有什么不同,是什么使它显式/隐式,以及如何使用"显式"关键字定义类构造函数(如果有的话)?
以下短节目
#include <vector>
#include <iostream>
std::vector<int> someNums()
{
return {3, 5, 7, 11};
}
class Woop
{
public:
Woop(const std::vector<int>& nums) : numbers(nums) {}
void report()
{
for (int i : numbers)
std::cout << i << ' ';
std::cout << '\n';
}
private:
const std::vector<int>& numbers;
};
int main()
{
Woop woop(someNums());
woop.report();
}
Run Code Online (Sandbox Code Playgroud)
有一个悬空引用问题,似乎没有编译器警告过。问题是临时文件可以绑定到 const-refs,然后您可以保留它。那么问题是;有没有办法避免陷入这个问题?最好是不涉及牺牲常量正确性或总是制作大对象的副本。
让我通过一个例子提出我的问题.
#include <memory>
std::unique_ptr<int> get_it() {
auto p = new int;
return p;
}
int main() {
auto up ( get_it() );
return 0;
}
Run Code Online (Sandbox Code Playgroud)
无法编译时出现以下错误:
a.cpp:5:9: error: could not convert ‘p’ from ‘int*’ to ‘std::unique_ptr<int>’
return p;
^
Run Code Online (Sandbox Code Playgroud)
为什么没有从原始指针自动转换为唯一的指针?我应该做什么呢?
动机:我理解使用智能指针清除所有权应该是一种好习惯; 我从某个地方得到一个指针(我拥有),就像int*在这种情况下一样,我(想想我)想要它unique_ptr.
如果您正在考虑评论或添加您自己的答案,请在提案N4029中解决Herbert Sutter关于此问题的论点.
您能否快速了解这4个关键字的用途以及原因?
我理解谷歌会在注册和易失性方面告诉你的基础知识,但想了解更多(仅仅是一个实用的概述).虽然做了相当低级的嵌入式系统代码,但是我从来没有找到过自己使用它们的理由,因此外部和明确地让我感到困惑.同样,我可以google但我更喜欢专家的快速,实用的总结,所以它坚持我的想法.
我在教科书和论坛中看到了很多代码,人们在for循环初始化中使用赋值运算符来开始重复.例如,
for ( int i = 0; i < 5; ++i ) // common
for ( int i(0); i < 5; ++i ) // uncommon
Run Code Online (Sandbox Code Playgroud)
我知道初始化变量比分配变量更快.为什么人们更喜欢前者呢?
我试图理解c ++中显式关键字的用法,并在SO上查看了这个问题. 显式关键字在C++中意味着什么?
但是,那里列出的例子(实际上都是前两个答案)对于使用情况不是很清楚.例如,
// classes example
#include <iostream>
using namespace std;
class String {
public:
explicit String(int n); // allocate n bytes to the String object
String(const char *p); // initializes object with char *p
};
String::String(int n)
{
cout<<"Entered int section";
}
String::String(const char *p)
{
cout<<"Entered char section";
}
int main () {
String mystring('x');
return 0;
}
Run Code Online (Sandbox Code Playgroud)
现在我已经将String构造函数声明为显式,但是如果我不将它列为显式,如果我将构造函数称为,
String mystring('x');
Run Code Online (Sandbox Code Playgroud)
要么
String mystring = 'x';
Run Code Online (Sandbox Code Playgroud)
在这两种情况下,我都会进入int部分.除非我指定值的类型,否则它默认为int.即使我使用参数更具体,例如将一个声明为int,另一个声明为double,而不是使用显式构造函数名称并以这种方式调用它
String mystring(2.5);
Run Code Online (Sandbox Code Playgroud)
或者这样
String mystring = 2.5;
Run Code Online (Sandbox Code Playgroud)
它总是默认为带有double参数的构造函数.所以,我很难理解显式的真实用法.你能给我一个例子吗?不使用显式将是一个真正的失败?
对"this"指针的操作是否会调用构造函数?
我有一个构造函数定义如下
Cents(int cents)
{
cout<<"in cents constructor\n";
m_cents = cents;
}
friend Cents operator + (const Cents &c1, const Cents &c2)
{
return Cents(c1.m_cents + c2.m_cents);
}
Cents operator ++ (int)
{
cout<<"In c++ function\n";
Cents c(m_cents);
*this = *this + 1 ;
return c;
}
Run Code Online (Sandbox Code Playgroud)
在主要功能我... ...
Cents c;
cout<<"Before post incrementing\n";
c++; //This part is calling the constructor thrice
Run Code Online (Sandbox Code Playgroud)
现在,如果我正在做一些像*this = *this + 1.它调用此构造函数两次.
究竟是怎么回事.是否*this创建临时对象并将值分配给原始对象?
由于两个原因,很难找到相关信息:
b2.它的帮助标志没有提到有关测试的任何内容.我想知道boost是否包含任何测试本身的测试.例如,许多优秀的开源库和应用程序有make check或make check-all或make test目标,但我不能尝试,因为这里升压不使用化妆.
我正在更改一个过去采用整数参数的旧例程,以便它现在采用对象的const引用.我希望编译器能告诉我调用函数的位置(因为参数类型错误),但是对象有一个构造函数,它接受一个整数,所以编译器创建一个临时对象,而不是失败,传递给它整数,并将对它的引用传递给例程.示例代码:
class thing {
public:
thing( int x ) {
printf( "Creating a thing(%d)\n", x );
}
};
class X {
public:
X( const thing &t ) {
printf( "Creating an X from a thing\n" );
}
};
int main( int, char ** ) {
thing a_thing( 5 );
X an_x( 6 );
return 1;
}
Run Code Online (Sandbox Code Playgroud)
我希望该X an_x( 6 )行不能编译,因为没有X构造函数需要int.但它确实编译,输出如下:
Creating a thing(5)
Creating a thing(6)
Creating an X from a thing …Run Code Online (Sandbox Code Playgroud) 我想要两个相似的模板,一个带有1个参数,另一个带有2个参数:
template<typename T1, typename T2=void>
struct foo {
T1 m_t1;
T2 m_t2;
foo(T1 t1, T2 t2) : m_t1(t1), m_t2(t2) {}
T1 t1() { return m_t1; }
T2 t2() { return m_t2; }
};
template<typename T1>
struct foo<T1,void> {
T1 m_t1;
foo(T1 t1) : m_t1(t1) {}
T1 t1() { return m_t1; }
};
Run Code Online (Sandbox Code Playgroud)
注意所有T1相关内容的代码重复.我怎么能避免这个?