我想在Union里面使用字符串.如果我写如下
union U
{
int i;
float f;
string s;
};
Run Code Online (Sandbox Code Playgroud)
编译器给出错误,说U :: S有复制构造函数.
我读了一些其他帖子,了解解决这个问题的其他方法.但我想知道为什么编译器首先不允许这样做?
编辑:@KennyTM:在任何联合中,如果成员被初始化,其他人将具有垃圾值,如果没有初始化,则所有将具有垃圾值.我认为,标记联合只是为从Union访问有效值提供了一些安慰.您的问题:您或编译器如何在没有额外信息的情况下为联合编写复制构造函数?sizeof(string)给出4个字节.基于此,编译器可以比较其他成员大小并分配最大分配(在我们的示例中为4字节).内部字符串长度无关紧要,因为它将存储在单独的位置.让字符串为任意长度.Union必须知道的是使用字符串参数调用字符串类复制构造函数.无论哪种方式编译器发现在正常情况下都必须调用复制构造函数,即使字符串在Union中,也要遵循类似的方法.所以我认为编译器可以这样做,分配4个字节.然后,如果为s分配了任何字符串,则字符串类将使用其自己的分配器来处理该字符串的分配和复制.所以也没有内存损坏的可能性.
编译器中Union开发时不存在字符串吗?所以我的答案还不清楚.我是这个网站的新工作人员,如果有什么不对,请原谅.
据说建造者模式适合比萨实例.
为什么不装饰?将奶酪,意大利辣香肠,培根作为基础披萨上的附加装饰品.
是因为奶酪/意大利辣香肠必须单独建造.我不认为,它们需要单独构建,因为它们可以随时可用.
请澄清一下.我也在寻找装饰模式的一个很好的现实世界的例子,以及为什么它适合那个特定的例子.谢谢.
赋值运算符可以使用成员函数重载,但不能使用非成员friend函数重载:
class Test
{
int a;
public:
Test(int x)
:a(x)
{}
friend Test& operator=(Test &obj1, Test &obj2);
};
Test& operator=(Test &obj1, Test &obj2)//Not implemented fully. just for test.
{
return obj1;
}
Run Code Online (Sandbox Code Playgroud)
它会导致此错误:
错误C2801:'operator ='必须是非静态成员
为什么friend函数不能用于重载赋值运算符?编译器允许重载其他运算符,例如+=和-=使用friend.支持的固有问题/限制是operator=什么?
我有这样的要求.对于一个函数,我将输入作为数字流.我的意思是,在每个调用中,函数继续使用单个数字进行调用.我正在使用队列来存储数字流.只有在满足某些条件时,我才需要处理一组收集的数字.如果条件不满足,我需要抛出队列中的所有元素,然后开始在其中存储新数字.为了清空队列,我找不到clear()方法.所以我循环如下.
while(!q.empty())
q.pop();
Run Code Online (Sandbox Code Playgroud)
我得到了有效的清算队列算法
我的问题是:为什么队列不支持clear()函数?
当deque和vector支持clear()方法时,支持队列的技术难度是什么?
或者我的上述用例非常罕见,因此不受支持?谢谢.
我在c ++标准(§9.5/ 1)中看到了以下内容:
工会不得有基类.联合不得用作基类.
联合可以具有成员函数(包括构造函数和析构函数),但不具有虚函数(10.3)
从上面,union也可以有构造函数和析构函数.
那么为什么在继承中不允许这样做?
编辑:回答评论:
如果允许union作为基类,则其数据可以由派生类使用.如果派生类有兴趣只使用union的一个成员,则这种方式可用于保存内存.我认为,这是不正当的继承.在这种情况下,在派生类中使用union更好吗?
如果允许union作为派生类,它可以使用基类服务.例如,如果Union有多种类型的数据.众所周知,只能使用一种数据.对于每种类型的数据,存在基类以为该特定类型提供服务.在这种情况下,可以使用多重继承来获取Union中所有类型数据的所有基类的服务.这也让我觉得继承的使用不当.但是,在这一点上是否有任何等效的概念来实现内容?
只是我的想法......
我需要以键值格式存储字符串.所以我正在使用如下的地图.
#include<map>
using namespace std;
int main()
{
map<string, string> m;
string s1 = "1";
string v1 = "A";
m.insert(pair<string, string>(s1, v1)); //Error
}
Run Code Online (Sandbox Code Playgroud)
我在插入行时遇到错误
错误C2784:'bool std :: operator <(const std :: _ Tree <_Traits>&,const std :: _ Tree <_Traits>&)':无法推断'const std :: _ Tree <_Traits>&'的模板参数来自'const std :: string'
我也尝试过make_pair函数,但是这也报告了同样的错误.
m.insert(make_pair(s1, v1));
Run Code Online (Sandbox Code Playgroud)
请告诉我什么是错的,以及解决上述问题的方法是什么.解决了上述问题后,我可以使用下面的方法来检索基于密钥的值
m.find(s1);
Run Code Online (Sandbox Code Playgroud) 我有以下代码,不编译:
int *p = new(nothrow) int;
delete (nothrow) p; //Error
Run Code Online (Sandbox Code Playgroud)
我得到的错误是:
错误C2440:'删除':无法从'const std :: nothrow_t'转换为'void*'
有nothrow版本delete存在吗?如果是这样,我该如何调用它?
在C++:The Complete Reference中,它给出了它存在,但我在网上看到了不同的意见,因此产生了混乱.
MSDN也谈到它的存在,但我找不到如何在代码中使用它.
在这里,有些人说没有这样的事情.
我有类的钻石层次结构:
A
/ \
B C
\ /
D
Run Code Online (Sandbox Code Playgroud)
为了避免D中的两个A副本,我们需要在B和C使用虚拟继承.
class A { };
class B: virtual public A {};
class C: virtual public A { };
class D: public B, public C { };
Run Code Online (Sandbox Code Playgroud)
问题:为什么需要在B和C上执行虚拟继承,即使模糊度在D?如果它在D处会更直观.
为什么标准委员会将此功能设计为这样?如果B和C类来自第三方库,我们该怎么办?
编辑:我的回答是指示B和C类,只要它的派生对象被创建,它们就不应该调用A的构造函数,因为它将被D调用.
我只是想检查编译器是否允许类型名称作为变量名称.我试过的时候
int int;
Run Code Online (Sandbox Code Playgroud)
它报告了一个错误说
错误C2632:'int'后跟'int'是非法的
但是当我尝试的时候
#include <string>
using namespace std;
int main()
{
string string;
}
Run Code Online (Sandbox Code Playgroud)
它没有给出任何错误.这两个string和int是数据类型.
为什么编译器允许string但不允许int?
编辑:包括更新.
编辑:有些人说int不是一个类.在这种情况下,为什么允许下面的行.
int a(10);
Run Code Online (Sandbox Code Playgroud)
它的工作方式类似于类的构造函数.
我从cplusplus.com获取以下代码:
// set_terminate example
#include <iostream>
#include <exception>
#include <cstdlib>
using namespace std;
void myterminate () {
cout << "terminate handler called\n";
abort(); // forces abnormal termination
}
int main (void) {
set_terminate (myterminate);
throw 0; // unhandled exception: calls terminate handler
return 0;
}
Run Code Online (Sandbox Code Playgroud)
由于代码中存在未处理的异常,因此需要调用myterminate()函数,该函数设置为终止处理程序并且应该覆盖默认的终止处理程序.
程序崩溃但没有调用myterminate().我使用的是Visual C++ 2008 Express Edition.
代码有什么问题?