我是C++的新手,我并不完全确定如何以安全的方式处理数组和指针.在我的班上,我有一个叫做项目的成员:
Item * items;
Run Code Online (Sandbox Code Playgroud)
在我的类方法read()中我打开一个文件并从这个文件中读取项目.我相应地分配空间:
items = new Item[item_count];
Run Code Online (Sandbox Code Playgroud)
item_count作为文件中的变量给出,并在创建任何项目之前预先读取.在我班级的解构器中,我再次释放这样的内存:
delete[] items;
Run Code Online (Sandbox Code Playgroud)
但是如果我read()在执行解构函数之前调用该方法两次,则第一个数组的内存将无法正确释放.我想在分配新内存之前事先在read方法中释放它.但是如何检查是否已为阵列分配了一些内存items?
编辑:我知道还有很多其他的可能性,更多的"现代"方法和更舒适的解决方案.但在这种情况下,我们明确告诉使用指针和数组(仅限教育目的).
我基本上理解托管和本机代码的概念及其区别.但他们在技术上如何相互沟通呢?想象一下以下示例:
我得到了一些为特定平台编译的静态或动态c ++库.现在我编写一个Java程序.在这段代码中,我使用'native'关键字调用库函数.我用字节码构建一个jar文件,c ++库文件将保持独立.结果将不再是与平台无关的.
但java程序如何知道调用的本机方法是否存在?
整个programmcode在运行时是如何执行的?我知道字节码将用JIT解释或编译.
这一切如何适合沙盒范例?本机代码是否也在沙箱中执行?
它是否有效,因为(java和c ++)代码到底都是机器代码?
也许这是一个愚蠢的问题.但我一直在想......
编辑:我有3个很好的答案.真的无法决定哪个对我帮助最大.但我会将这个问题标记为已经回答,以便从我这边关闭这个话题.
也许这是一个简单的问题,因为我还是C++的新手.我想使用某种工厂来封装我的应用程序中的日志记录.这个想法是只有工厂知道哪个具体类将处理函数调用.应用程序将始终调用基本日志记录类的抽象接口.
工厂方法应如下所示:
std::unique_ptr<AbstractLoggingClass> Factory::getDefaultLogger(const std::string& param){
return new ConcreteLoggingClass(param);
}
Run Code Online (Sandbox Code Playgroud)
ConcreteLoggingClass是.的子类AbstractLoggingClass.
但是我收到以下错误:
Error: could not convert '(operator new(64ul), (<statement>,
((ConcreteLoggingClass*)<anonymous>)))' from 'ConcreteLoggingClass*'
to 'std::unique_ptr<AbstractLoggingClass>'
Run Code Online (Sandbox Code Playgroud)
我的问题是,我不知道如何实例化ConcreteLoggingClass并返回unique_ptr到AbstractLoggingClass
我已经找到了这篇文章,但我仍然没有看到解决方案.
我得到了以下场景:C++ 服务器应用程序正在侦听传入的客户端连接。每次客户端连接尝试都会生成一个新会话。此会话将调用特定服务,具体取决于服务 id,该服务 id 在来自客户端的序列化数据中提供。一旦结果从服务到达,会话就会将数据发送到客户端。
该场景的缺陷在于,该服务是用 Java 实现的。
因此我的问题是:
我知道为此我需要一个 Java VM。并且因为 C++ 服务器类将首先从 Java 应用程序调用(通过 SWIG 生成的包装器),所以我想我可能会将这个应用程序的 VM 引用传递给我的服务器类(以及之后的会话)。
但:
通常,Java 应用程序在启动服务器后什么也不做。也许我将不得不让它保持空闲状态以保持 VM 引用处于活动状态?对于 C++ 和 Java 交互中对服务的并发调用(超出服务内部的正常并发处理),我有什么特别需要担心的吗?
例子:
//Java Service
public class JMyService{
public String loadContactInformation(int userid){
return "test";
}
}
//C++ (very simplified)
class Session{
public:
//[...]
void handleWrite(){
vm = getVMReference(); //is saved beforehand
if(serviceId == CONTACT_INFO){
//todo call JMyService.loadContactInformation
}
}
}
Run Code Online (Sandbox Code Playgroud)
我已经看到了 …
我有一个客户端和一个服务器应用程序,它们将使用 Asio(独立)库相互发送数据。这两个应用程序由两个(逻辑)部分组成:
让我们假设复杂对象已经使用Protocoll Buffers进行了序列化,并且应用程序的低级部分从高级部分接收数据作为 std::string。我想使用Protocoll Buffers 的这个函数来完成这项工作:
bool SerializeToString (string* output) const;:序列化消息并将字节存储在给定的字符串中。请注意,字节是二进制的,而不是文本;我们只使用字符串类作为方便的容器。
并说我在客户端使用 async_write 传输此数据:
size_t dataLength = strlen(data);
//writes a certain number of bytes of data to a stream.
asio::async_write(mSocket,
asio::buffer(data, dataLength),
std::bind(&Client::writeCallback, this,
std::placeholders::_1,
std::placeholders::_2));
Run Code Online (Sandbox Code Playgroud)
如何在服务器端读取这些数据?我不知道我需要阅读多少数据。因此这将不起作用(长度未知):
asio::async_read(mSocket,
asio::buffer(mResponse, length),
std::bind(&Server::readCallback, this,
std::placeholders::_1,
std::placeholders::_2));
Run Code Online (Sandbox Code Playgroud)
解决这个问题的最佳方法是什么?我可以想到两个解决方案:
data并阅读,直到我到达这个“数据信号结束”。问题是,如果这个角色以data某种方式出现怎么办?我不知道 Protocoll Buffers 如何序列化我的数据。size_of_data + data而不是data。但是我不知道如何以独立于平台的方式序列化大小,将其添加到二进制数据中并再次提取。编辑:也许我可以用这个:
uint64_t length = strlen(data);
uint64_t nwlength = htonl(length);
uint8_t len[8];
len[0] = …Run Code Online (Sandbox Code Playgroud) 作为 C++ 新手,我想知道为什么显式“禁用”或删除类的 = 运算符和复制构造函数很有用:
SomeClass& operator=(SomeClass&) = delete;
SomeClass(SomeClass&) = delete;
Run Code Online (Sandbox Code Playgroud)
我想如果该类是单身人士,这是有道理的。但是还有其他情况吗?(也许这与性能问题有关?)
我下载了Boost 的 Asio Library的最新独立版本。现在我想将仅头文件库集成到一个简单的 qt Creator C++ 项目中。但是,如果我尝试运行包含 asio.hpp 的“hello world”示例,我会收到以下错误消息(请参阅下面的完整错误消息):
asio/detail/config.hpp: No such file or directory
Run Code Online (Sandbox Code Playgroud)
这些是我迄今为止采取的步骤
在 .pro 文件中指定应使用 c++11
配置+=c++11
此外,我尝试在我的 main 中添加以下定义:
Run Code Online (Sandbox Code Playgroud)#define ASIO_STANDALONE #define ASIO_HAS_STD_ADDRESSOF #define ASIO_HAS_STD_ARRAY #define ASIO_HAS_CSTDINT #define ASIO_HAS_STD_SHARED_PTR #define ASIO_HAS_STD_TYPE_TRAITS #include <iostream> #include "libs/asio/include/asio.hpp" using namespace std; int main() { cout << "Hello World!" << endl; return 0; }
看来 qmake 不知道所有包含。我对 cmake、qmake 之类的东西不太熟悉。因此,作为菜鸟,我尝试在 .pro 文件中添加新的 INCLUDEPATH …