我必须将相同的字符串(例如日志消息)发送到多个流.
以下哪种解决方案效率最高?
为每个流重建相同的字符串并将其发送到流本身.
outstr1 << "abc" << 123 << 1.23 << "def" << endl;
outstr2 << "abc" << 123 << 1.23 << "def" << endl;
outstr3 << "abc" << 123 << 1.23 << "def" << endl;
Run Code Online (Sandbox Code Playgroud)使用字符串的运算符构建字符串一次,并将其发送到所有流.
std::string str = "abc" + std::to_string(123) + std::to_string(1.23) + "def";
outstr1 << str;
outstr2 << str;
outstr3 << str;
Run Code Online (Sandbox Code Playgroud)使用流构建字符串一次,并将其发送到所有流:
std::stringstream sstm;
sstm << "abc" << 123 << 1.23 << "def" << endl;
std::string str = sstm.str();
outstr1 << str;
outstr2 << str; …Run Code Online (Sandbox Code Playgroud)用WinDbg调试时我看不到局部std::string变量的值.我可以看到布尔变量的值,但是当将鼠标悬停在字符串变量上或在Locals窗口中查看时,我看到的只是变量的类型而不是它的实际值.
如何查看局部std::string变量的值?
我正在派生我自己的异常,调用它MyException,std::system_error从而重写what()以计算并返回我的消息.MyException的初始化列表不会调用带有消息的system_error构造函数覆盖.
如果我抓住一个MyException,并将其复制到std::exception调用的结果what()上std::exception就是nullptr.这是有道理的.
我的问题是,如果我确实使用了在初始化时接收消息的system_exception的构造函数MyException,是否指定system_error将获取消息的副本并拥有它并释放它?
我假设这将使std::exception副本MyException能够返回有效的what().虽然我会在每次MyExceptions创建新内容时计算"什么"需要考虑性能.只有在首次调用what()时,我才能懒惰地计算它.
我有点担心'what'字符串的所有权what()返回a char*而不是a const std::string&.
代码是这样的(我还没有编译):
class MyException : public std::system_error
{
std::string what_;
public:
MyException(int errorValue, const std::error_category& category)
: std::system_error(errorValue, category)
{}
char* what() const
{
what_ = "MyException: " + to_string(code().value());
return what_.c_str();
}
};
int main()
{
std::exception ex;
try
{ …Run Code Online (Sandbox Code Playgroud) C++中std :: string的底层结构是什么?
据我所知,有两个不同的概念:
1)整个字符串用char指针(char*)实现.
2)字符串的某些部分使用静态数组实现.它的大小等于40,如果字符串的长度超过40,则分配动态内存.
哪一个是正确的?
我创建了简单的C ++ std::string值。
但是该值会产生意想不到的结果。
我使用g ++编译器(Linux)和Visual Studio(Windows)测试了此代码,并且两个编译器都出现相同的问题。
正常结果码
/* This code results are Normal */
#include <bits/stdc++.h>
int main() {
std::string a1 = "a1";
std::string a2 = "a2";
std::string b1("b1");
std::string b2("b2");
const char *c1 = std::string("c1").c_str();
const char *c2 = std::string("c2").c_str();
std::cout << "Expected [a1], real [" << a1 << "]\n";
std::cout << "Expected [a2], real [" << a2 << "]\n";
std::cout << "Expected [b1], real [" << b1 << "]\n";
std::cout << "Expected [b2], real [" << …Run Code Online (Sandbox Code Playgroud) 我试图通过 string_view 将一些字符串保存到第二个数据容器,但遇到了一些困难。事实证明,字符串在 move() 之后改变了它的底层数据存储。
我的问题是,为什么会发生这种情况?
例子:
#include <iostream>
#include <string>
#include <string_view>
using namespace std;
int main() {
string a_str = "abc";
cout << "a_str data pointer: " << (void *) a_str.data() << endl;
string_view a_sv = a_str;
string b_str = move(a_str);
cout << "b_str data pointer: " << (void *) b_str.data() << endl;
cout << "a_sv: " << a_sv << endl;
}
Run Code Online (Sandbox Code Playgroud)
输出:
a_str data pointer: 0x63fdf0
b_str data pointer: 0x63fdc0
a_sv: bc
Run Code Online (Sandbox Code Playgroud)
感谢您的回复!
从Strings in Depth,我了解到C++标准没有定义字符串类的内存布局的确切实现.但是,如何来&string和&string[0]将有不同的内存地址?
string variable("String Test");
cout << (void *) &variable << endl; // 003EFE58
cout << (void *) &variable[0] << endl; // 003EFE5C
cout << (void *) &variable[1] << endl; // 003EFE5D
... ...
Run Code Online (Sandbox Code Playgroud)
但他们确实共享相同的内容,请查看:
cout << ((string)*(&variable))[0] << endl; // 'S'
cout << *(&variable[0]) << endl; // 'S'
Run Code Online (Sandbox Code Playgroud)
谁能解释一下这里发生了什么?
我总是删除数组delete[].但HP Fortify显示出内存泄漏.我的代码出了什么问题?
unsigned buflen = SapUcConverter::getFormatBufferLength(len);
char* buffer = new char[buflen]; // Here is the memory leak marked by Fortify
if(valueCanBeLogged) {
LOGMSG(_DBUG, "nameForLog=%s, len=%d, sapuc='%.*s'",
nameForLog, len, buflen,
SapUcConverter::format(buffer, sapuc, len));
} else {
LOGMSG(_DBUG, "nameForLog=%s, len=#####, sapuc=#####");
}
delete[] buffer;
Run Code Online (Sandbox Code Playgroud) 我试图理解使用WidgetURef::setName(URef作为一个通用参考,由Scott Meyers创造的术语)与WidgedRRef::setName(RRef作为R值参考)的性能影响:
#include <string>
class WidgetURef {
public:
template<typename T>
void setName(T&& newName)
{
name = std::move(newName);
}
private:
std::string name;
};
class WidgetRRef {
public:
void setName(std::string&& newName)
{
name = std::move(newName);
}
private:
std::string name;
};
int main() {
WidgetURef w_uref;
w_uref.setName("Adela Novak");
WidgetRRef w_rref;
w_rref.setName("Adela Novak");
}
Run Code Online (Sandbox Code Playgroud)
我很欣赏通用引用应该使用std::forward,但这只是一个(不完美的)示例,以突出有趣的位.
问题
在这个特定的例子中,使用一个实现与另一个实现的性能影响是什么?虽然WidgetURef需要类型扣除,但它在其他方面是相同的WidgetRRef,不是吗?至少在这种特殊情况下,在两种情况下,参数都是r-value引用,因此不会创建临时值.这个推理是否正确?
背景
这个例子来自Scott Meyers的"Effective Modern C++"(p.170)的第25项.根据这本书(假设我的理解是正确的!),采用通用引用的版本T&&不需要临时对象而另一个需要临时对象std::string&&.我真的不明白为什么.
如果我声明一个 std::string 类型的变量但不初始化它,则分配多少内存?我知道,如果我将其初始化为“hello”,那么将为每个字符保留一个字节,加上一个空字符,总共 6 个字节。字符串类中是否定义了默认长度?(我尝试在字符串头文件中查找实际定义,但不知道在哪里找到它)