我有一个简单的结构Wrapper,由两个模板化赋值运算符重载区分:
template<typename T>
struct Wrapper {
Wrapper() {}
template <typename U>
Wrapper &operator=(const Wrapper<U> &rhs) {
cout << "1" << endl;
return *this;
}
template <typename U>
Wrapper &operator=(Wrapper<U> &rhs) {
cout << "2" << endl;
return *this;
}
};
Run Code Online (Sandbox Code Playgroud)
然后我宣布a和b:
Wrapper<float> a, b;
a = b;
Run Code Online (Sandbox Code Playgroud)
分配b到a将使用非const模板赋值操作过载从上方和数字"2"被显示.
令我困惑的是:如果我宣布c和d,
Wrapper<float> c;
const Wrapper<float> d;
c = d;
Run Code Online (Sandbox Code Playgroud)
并且分配d给c,既没有使用两个赋值运算符重载,也没有显示输出; 因此调用默认的复制赋值运算符.为什么分配d到c未使用const重载赋值操作符提供?或者相反,为什么分配b给a …
有人可以证明在Singleton类实现中需要对赋值运算符进行私有化吗?
Singleton& operator=(Singleton const&);私有化解决了什么问题?
class Singleton {
public:
static Singleton& Instance() {
static Singleton theSingleton;
return theSingleton;
}
private:
Singleton(); // ctor hidden
Singleton(Singleton const&); // copy ctor hidden
Singleton& operator=(Singleton const&); // assign op. hidden
~Singleton(); // dtor hidden
};
Run Code Online (Sandbox Code Playgroud) 我知道我可以像这样使用逗号运算符
for (int i = 1, j = 15; j>10; i++, j--) {
// do something neat
}
Run Code Online (Sandbox Code Playgroud)
但是有些文章似乎暗示逗号运算符可以在for循环声明之外使用,例如
int j = 2, k = 4 ;
int x ;
// Assignment statement with comma operator
x = j + 1, k ;
Run Code Online (Sandbox Code Playgroud)
来源:http://www.cs.umd.edu/~clin/MoreJava/ControlFlow/comma.html
要么
int x = (expression) ? (i++,2) : 3;
Run Code Online (Sandbox Code Playgroud)
来源:https://stackoverflow.com/a/12047433/1084813
对于代码混淆竞赛来说这将是一个巧妙的技巧或混淆我的同事,但两个示例都不会编译(Java 1.6,Eclipse Juno),错误是"赋值的左侧必须是变量".我试着查看编译器设置,看看是否可以禁止防止错误的代码,但没有运气.
怎么了?逗号运算符是旧规范的一部分,后来又改变了吗?使用不同Java设置编写这些示例的人是否允许这样做?
java for-loop variable-assignment comma-operator assignment-operator
通常,给定某种类型T,要实现复制和移动赋值,需要两个函数
T& operator=(T&&) { ... }
T& operator=(const T&) { ... }
Run Code Online (Sandbox Code Playgroud)
最近,我逐渐意识到单一的就足够了
T& operator=(T v) {
swap(v);
return *this;
}
Run Code Online (Sandbox Code Playgroud)
此版本利用了复制/移动构造函数.赋值是复制还是移动取决于v构造方式.这个版本甚至可能比第一个版本更快,因为pass-by-value允许更多的空间用于编译器优化[1].那么,即使标准库使用它,第一个版本优于第二个版本的优势是什么?
[1]我想这解释了为什么标签和函数对象在标准库中按值传递.
class A, B;
class A {
public:
A& operator= ( const A &rhs ) { return *this; }
};
class B: public A {
public:
B& operator= ( const A &rhs ) { return *this; }
};
A a;
B b;
std::list < A > aa;
std::list < B > bb;
a = b; // works
b = a; // works
// aa = bb; // fails
// bb = aa; // fails
Run Code Online (Sandbox Code Playgroud)
如何让bb = aa工作?
我同意这样的共识,即通常最好在成员初始化列表中初始化C++数据成员而不是构造函数的主体,但我对此解释持怀疑态度
构建构造函数的另一种(低效)方法是通过赋值,例如:
Fred::Fred() { x_ = whatever; }.在这种情况下,表达式会导致创建单独的临时对象,并且此临时对象将传递到x_对象的赋值运算符中.然后该临时对象被破坏了;.那效率很低.
这实际上是对的吗?我原以为编译器会忽略默认构造的临时对象,该对象会立即被正文中的赋值所取代.我不知道为什么我预料到这一点,但阅读了上述说法,我想我已经悄悄地假设了多年.
成员初始化列表实际上更有效吗?如果是这样,是因为这个原因吗?
c++ performance constructor member-initialization assignment-operator
这是我对Stackoverflow的第一个问题,尽管我多年来一直是消费者.如果我违反规则,请原谅我.那肯定不是我的意图.我已经严格审查了规则并相信我处于可接受的范围内.但是,我会要求您指出使用错误,如果它们存在,以便我将来可能更符合要求.
我教高中生编程.这个学期我们正在做C#.上周我们正在研究递归.我分配了几个可以通过递归解决的经典问题,其中一个是取幂.
我的一个学生提交了以下代码作为使用递归的取幂的解决方案(他确实允许我在这里发布).方法调用中的任务给了我很多的意思,但当我告诉他这是不好的做法时,他抗议说"它有效",对他"有意义",他"一直都这样做" ".
static void Recur(int n1, int n2, int n3)
{
if (n2 > 0)
{
Recur(n1, n2 - 1, n3 *= n1); // this is the line in question
}
else
{
Console.WriteLine("The number calculated recursively is: {0}", n3);
}
}
Run Code Online (Sandbox Code Playgroud)
我很难想出具体的东西来告诉我的学生为什么在方法调用中进行分配通常是不好的做法,除了1)意外副作用的可能性,以及2)维护的难度.
我已经在网上搜索了我可以构建的关于这个问题的每一个短语,但是我已经空手而归了.我确实看到了罗伯特·C·马丁的一本名为"清洁代码"的书,我并不拥有.
我与学生的关系有点像父母的关系.除非我能用独立的资料证明,否则他们有时候不会把大量的股票放在我所说的内容中.如果我可以指出一个关于在一个方法调用中放置任务的明确声明,我的学生将更倾向于停止这种烦人的习惯.
这种用法是否会困扰其他人?我是否希望他改变他一直做事的方式?他已经15岁了,但在他前面有一个充满希望的未来.他是那些只是"得到它"的学生之一.我不希望他发展不良做法.
感谢您的时间和意见.
在C++中重载类的赋值运算符时,它的参数必须是引用吗?
例如,
class MyClass {
public:
...
MyClass & operator=(const MyClass &rhs);
...
}
Run Code Online (Sandbox Code Playgroud)
是真的吗
class MyClass {
public:
...
MyClass & operator=(const MyClass rhs);
...
}
Run Code Online (Sandbox Code Playgroud)
?
谢谢!
我最近重新访问了复制构造函数,赋值运算符,这里看到的复制交换idom: 什么是复制和交换习惯用法? 和许多其他地方 -
上面的链接是一个很好的帖子 - 但我还有一些问题 - 这些问题可以在很多地方,stackoverflow和许多其他网站上得到解答,但我没有看到很多一致性 -
1 - 您是否应该try- catch在我们为复制构造函数中的深层复制分配新内存的区域周围?(我已经看到了两种方式)
2 - 关于复制构造函数和赋值运算符的继承,何时应该调用基类函数,何时这些函数应该是虚函数?
3 - std::copy复制构造函数中复制内存的最佳方法是什么?我已经看过了memcpy,看到其他人说memcpy世界上最糟糕的事情.
考虑以下示例(感谢所有反馈),它提示了一些其他问题:
4 - 我们应该检查自我分配吗?如果是这样的话
5 - 关闭主题问题,但我看到swapped用作:
std::copy(Other.Data,Other.Data + size,Data);
应该是:
std::copy(Other.Data,Other.Data + (size-1),Data);
如果swap从'First到Last'而第0个元素是Other.Data?
6 - 为什么注释掉的构造函数不起作用(我必须将大小更改为mysize) - 假设这意味着无论我编写它们的顺序如何,构造函数将始终首先调用分配元素?
7 - 对我的实施还有其他评论吗?我知道代码没用,但我只想说明一点.
class TBar
{
public:
//Swap Function
void swap(TBar &One, TBar &Two)
{
std::swap(One.b,Two.b);
std::swap(One.a,Two.a);
}
int a;
int *b;
TBar& operator=(TBar Other)
{
swap(Other,*this);
return (*this);
}
TBar() : …Run Code Online (Sandbox Code Playgroud) 我在Java中有2个ArrayLists:
mProductList = new ArrayList<ProductSample>();
mProductList2 = new ArrayList<ProductSample>();
mProductList = productSampleList;
mProductList2 = productSampleList;
mProductList2 .remove(3);
Run Code Online (Sandbox Code Playgroud)
productSampleList的大小为5.为什么在执行此段代码之后.mProductList的大小是4?
我们有办法避免这种情况吗?我希望mProductList的大小为5,与productSampleList相同.
谢谢!
c++ ×7
constructor ×2
inheritance ×2
java ×2
c# ×1
c++11 ×1
deep-copy ×1
for-loop ×1
methods ×1
move ×1
performance ×1
reference ×1
side-effects ×1
singleton ×1
stdlist ×1
templates ×1