一个初级开发人员问我是否可以为具有POD参数的联合重载赋值运算符,以便当将union的实例分配给该类型的变量时,将写入union中的相应数据类型.我回答说我不这么认为,但后来玩了下面的代码.令我惊讶的是这段代码实际编译(在Ubuntu 12.04上使用g ++版本4.6.3)
union unMember
{
float fData;
unsigned int uiData;
unMember():uiData(0) {};
unMember(float data):fData(data) {};
unMember(unsigned int data):uiData(data) {};
operator float() {return fData;};
operator unsigned int() {return uiData;};
unMember& operator=(float data) {fData = data;return *this;};
unMember& operator=(unsigned int data) {uiData = data; return *this;};
float GetFloat() const {return fData;};
};
int main () {
float fTest = 1.0;
unsigned int uiTest = 10;
unMember data = fTest;
unMember data2 = uiTest;
unMember data3 = data2;
float f = data.GetFloat(); …Run Code Online (Sandbox Code Playgroud) 在几分钟前看到这个问题之后,我想知道为什么语言设计者允许它,因为它允许间接修改私人数据.举个例子
class TestClass {
private:
int cc;
public:
TestClass(int i) : cc(i) {};
};
TestClass cc(5);
int* pp = (int*)&cc;
*pp = 70; // private member has been modified
Run Code Online (Sandbox Code Playgroud)
我测试了上面的代码,实际上私有数据已被修改.有没有解释为什么允许这种情况发生,或者这只是对语言的疏忽?它似乎直接破坏了私人数据成员的使用.
我不得不将应用程序从C++重写为C.我在Ubuntu 12.04上使用gcc和Eclipse.这样做我遇到了这个错误
../src/TTNoddy.c: In function ‘main’:
../src/TTNoddy.c:16:2: error: unknown type name ‘timespec’
Run Code Online (Sandbox Code Playgroud)
这是我的代码片段,可以重现问题
#include <time.h>
int main(void) {
timespec TS;
TS.tv_nsec = 1;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我在这里很困惑 - 我是一名C++程序员,从来没有在我的生活中编写过纯粹的C应用程序,但是man页面clock_gettime清楚地表明timespec我在这里包含的time.h头文件中找到了它.我错过了什么?
我很高兴在我的代码中使用C++样式的转换操作符,但我不能说我真的理解幕后发生的事情.我基本上想知道在以下短进程中指针实际发生了什么:
class A {};
class B : public A {};
class C : public B {};
A* pC = new C();
B* b = static_cast<B*>(pC); // Is the value of pC changed by the cast?
C* c = static_cast<B*>(pC); // Is the value of pC changed by the cast?
B* b2 = static_cast<B*>(c) // Is the value of c now equal to the value of b2?
Run Code Online (Sandbox Code Playgroud)
我意识到指向的对象pC总是类型,C但在第一次转换后,我假设存储的地址b不再等于pC.但如果演员改变了pC我的假设的价值是错误的.简而言之,强制转换操作符实际上是否可以更改它们所投射的指针的地址?这似乎是一个非常简单的问题,但在我看来,图片并不清楚如何将具有继承层次结构的对象存储在内存中以及如何通过强制转换操纵指针.
在我的脑海中, …
我正在用C++编写Ubuntu Linux上的应用程序来从串口读取数据.它通过我的代码调用成功地工作select(),然后ioctl(fd,FIONREAD,&bytes_avail)在最终获得数据之前找出可用的字节数read().
我的问题是:每次select返回数据时,可用的字节数报告为8.我猜这是一个缓冲区大小设置在某处,当这个缓冲区已满时,select会向用户返回通知.
我不熟悉Linux作为开发人员(但不是C++的新手),我试图研究(没有成功)是否可以改变这个缓冲区的大小,或者确实如果我的假设是真的.在我的应用程序中,时序至关重要,只要读缓冲区中有新字节,我就需要发出警报.这可能,而不深入研究内核代码?
我在Ubuntu 12.04上构建了一个应用程序,并尝试在嵌入式系统上运行它.我跑apt-cache show libc6了我的开发机器,显示(除其他外)
Package: libc6
Priority: required
Section: libs
Architecture: i386
Source: eglibc
Version: 2.15-0ubuntu10
Replaces: belocs-locales-bin, libc6-i386
Provides: glibc-2.13-1, libc6-i686
Run Code Online (Sandbox Code Playgroud)
嵌入式设备上存在的libc6版本为2.8.90.在\lib设备上的目录中,我有2个库
libc-2.8.90.so
libc.so.6
Run Code Online (Sandbox Code Playgroud)
当我将我的应用程序复制到嵌入式设备上时,我收到以下错误
/usr/lib/libc.so.6: version `GLIBC_2.15` not found (required by ./ServerSocketApp)
Run Code Online (Sandbox Code Playgroud)
我知道如果可能的话,当我在开发机器上构建应用程序时,我需要强制它链接到嵌入式设备上存在的相同版本的libc6.我遇到的问题是我根本不知道该怎么做.我发现的任何答案对我来说都毫无意义.是否有一些选项需要传递给g ++以使其链接到版本2.8.90 ??
绝望中我想是可以将我的开发机器上的libc复制到嵌入式设备上代替已经存在的东西并希望最好的??? 我似乎无法在网上找到任何文件,用简单的术语解释你如何解决这个问题,所以任何建议都会非常受欢迎,因为我在这里撕裂我的头发.
我正在使用套装.我使用自定义结构作为键.我正在插入一个值并尝试查找插入的值.但它似乎永远找不到元素.
我已经覆盖了==运算符和<运算符.
这是结构的代码:
struct distance_t
{
public:
int id;
double distance;
bool operator<(const distance_t& rhs) const
{
if(distance < rhs.distance)
return true;
else
return false;
}
bool operator==( const distance_t& rhs)
{
if(id == rhs.id)
return true;
else
return false;
}
};
Run Code Online (Sandbox Code Playgroud)
这是主要的代码
int main()
{
set<distance_t> currentSet;
distance_t insertDistance;
insertDistance.id =1;
insertDistance.distance = 0.5;
currentSet.insert(insertDistance);
distance_t findDistance;
findDistance.id = 1;
assert(currentSet.find(findDistance) != currentSet.end());
}
Run Code Online (Sandbox Code Playgroud)
它总是在assert语句中失败.我究竟做错了什么?
编辑-Ok现在我明白它根本不使用==运算符.这就是我想要的.我需要按距离排序数据结构.但我应该能够使用id删除它.有没有干净的方法或已有的数据结构来做到这一点?
我之前读过一个因为与此完全重复而被关闭的问题
和
但读完之后我仍然对sizeof()的工作原理感到困惑.我理解将数组作为参数传递给函数,如
void foo(int a[5])
Run Code Online (Sandbox Code Playgroud)
将导致数组参数衰减为指针.我在上面的2个问题链接中找不到的是一个明确的答案,为什么sizeof()函数本身免于(或至少看似豁免)这个指针衰减行为.如果sizeof()表现得像任何其他函数那么
int a[5] = {1,2,3,4,5};
cout << sizeof(a) << endl;
Run Code Online (Sandbox Code Playgroud)
然后上面应该输出4而不是20.我是否错过了一些明显的东西,因为这似乎与指针行为的衰退相矛盾?很抱歉再次提起这个问题,但我真的很难理解为什么会发生这种情况,尽管多年来一直很愉快地使用这个功能而没有真正考虑它.
可能重复:
如何重用ostringstream?
我一直在使用std::ostringstream转换float和int值到字符串但我无论如何都找不到重用实例.为了说明我的意思,以下是我尝试用来清除流的方法
#include <iostream>
#include <sstream>
using namespace std;
int main() {
ostringstream stream;
stream << "Test";
cout << stream.str() << endl;
stream.flush();
stream << "----";
cout << stream.str() << endl;
stream.clear();
stream << "****";
cout << stream.str() << endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
生成输出
Test
Test----
Test----****
Run Code Online (Sandbox Code Playgroud)
这给了我一个问题,因为我不得不创建许多ostringstream浪费的实例.显然clear(),flush()不要做我需要的,所以有办法做到这一点吗?我查看了http://www.cplusplus.com/reference/iostream/ostringstream/上的文档,但似乎没有任何内容可以满足我的需求.有没有办法重置或清除流?
我需要以这样一种方式实现(在C++中)线程安全容器,只有一个线程能够从容器中添加或删除项目.我之前通过在线程之间共享互斥锁来完成此类操作.这会导致很多互斥对象在我的代码中被乱丢,并且使得事情变得非常混乱并且难以维护.
我想知道是否有更整洁,更面向对象的方式来做到这一点.我想到了容器周围的以下简单类包装器(半伪C++代码)
class LockedList {
private:
std::list<MyClass> m_List;
public:
MutexObject Mutex;
};
Run Code Online (Sandbox Code Playgroud)
这样可以通过以下方式完成锁定
LockedList lockableList; //create instance
lockableList.Mutex.Lock(); // Lock object
... // search and add or remove items
lockableList.Mutex.Unlock(); // Unlock object
Run Code Online (Sandbox Code Playgroud)
所以我的问题是从设计的角度来看这是否是一个好的方法?我知道从设计的角度来看,允许公众访问成员是不受欢迎的,上述设计是否存在任何严重缺陷.如果是这样,有更好的方法来实现线程安全的容器对象?
我已经阅读了很多关于设计和C++的书籍,但似乎确实存在关于多线程编程和多线程软件设计的文献缺失.
如果以上是解决问题的一种不好的方法,我可以有人建议一种方法来改进它,或者指出一些信息,解释设计类是线程安全的好方法??? 非常感谢.