相关疑难解决方法(0)

按值返回不会创建新对象

我想尝试一下我读到的关于在C++中按值返回的内容(它与在新对象中创建时传递值相同)我有这样的代码:

#include <iostream>

using namespace std;

class Kar{

public:
    int n;
    static int no;

    Kar(){
        n = ++Kar::no;
        cout << "Creating Kar " << n << endl;
    }

    Kar(Kar &k){
        n = ++Kar::no;
        cout << "Copying Kar " <<k.n<< " to new Kar " << n << endl;
    }

    ~Kar(){
        cout << "Destroying Kar "<< n << endl;
    }

    Kar& operator= (const Kar &k);
};


Kar& Kar::operator= (const Kar &k){

    cout << "Assigning Kar "<< k.n <<" to Kar "<< …
Run Code Online (Sandbox Code Playgroud)

c++

6
推荐指数
1
解决办法
180
查看次数

这个回报声明中发生了什么?

我正在阅读复制文章(以及它应该如何在C++ 17中得到保证),这让我有点困惑(我不确定我知道我以前认识的事情).所以这是一个最小的测试用例:

std::string nameof(int param)
{
    switch (param)
    {
    case 1: 
        return "1"; // A
    case 2: 
        return "2" // B
    }
    return std::string(); // C
}
Run Code Online (Sandbox Code Playgroud)

我看到它的方式,情况A和B对返回值执行直接构造,因此复制省略在这里没有意义,而案例C不能执行复制省略,因为有多个返回路径.这些假设是否正确

另外,我想知道是否

  • 有写了上一个更好的方法(例如有一个std::string retval;总是返回一个或写入的情况下A,并B作为return string("1")等)
  • 有任何移动发生,例如"1"是暂时的,但我假设它被用作构造函数的参数std::string
  • 我有一个优化问题(例如我认为C可以写成return{},这会是一个更好的选择吗?)

c++ stl

6
推荐指数
1
解决办法
232
查看次数

为什么不能为这个C++代码示例打印两次解构?

using namespace std;

Object returnObject(){
    Object o;  
    return o;  //place A
 }

int main() {
    Object CopiedO=returnObject();  
    return 0;  //Place B
}
Run Code Online (Sandbox Code Playgroud)

对象定义是:

Object::Object() {
    cout<<"Object::Object"<<endl;
}

Object::~Object() {
    cout<<"Object::~Object"<<endl;
}

Object::Object(const Object& object) {
    cout<<"Object::CopyObject"<<endl;
}
Run Code Online (Sandbox Code Playgroud)

结果是:

/*Object::Object
Object::~Object*/
Run Code Online (Sandbox Code Playgroud)

据我所知,o和CopiedO都将被解构,但为什么只有一次打印Object ::〜Object?

我认为没有内联,复制的o是o的副本.但是它不能打印Object :: CopyObject

c++ copy

5
推荐指数
1
解决办法
141
查看次数

使用构造函数的术语是什么?

一位同事编写了以下代码,我确信这是错误的.

我想向他解释问题,但不知道正确的术语,所以我找不到支持我的立场的参考资料:

他的代码:

BSTR someString = _bstr_t(L"Hello World");
Run Code Online (Sandbox Code Playgroud)

为什么我认为它是错误的:
我相信它会_bstr_t(L"Hello World");调用构造函数_bstr_t,并创建一个该类型的短期临时变量.在该行代码之后(在分号序列点之后),该临时符将被自动删除,并且其字符串空间被释放.
这将someString指向已释放的内存.

问题:
构造函数调用的正确术语是什么?

你能指出一些描述使用细节的参考/术语/页面吗?

临时_bstr_t对象有术语吗?
我想我会称之为"匿名,临时变量",但我不知道这在技术上是否准确.

(或者在我的分析中我可能完全错了......如果是的话,我很想知道)


为了澄清:

_bstr_t是一个C++类,Microsoft通常用它来包装它们的BSTR类型,所以它有构造函数/析构函数/运算符等.

BSTR是一个只有a的typedef WCHAR*,所以它没有任何逻辑.它只是一个愚蠢的指针.

c++ com constructor bstr

5
推荐指数
2
解决办法
160
查看次数

为什么在运算符重载时返回允许的构造函数?

为什么在运算符重载时返回允许的构造函数?

这是一个例子:

Complex Complex::operator*( const Complex &operand2 ) const
{
    double Real = (real * operand2.real)-(imaginary * operand2.imaginary);
    double Imaginary = ( real * operand2.imaginary)+(imaginary * operand2.real);

    return Complex ( Real, Imaginary );
}
Run Code Online (Sandbox Code Playgroud)

它似乎是返回对象的构造函数而不是对象本身?什么回到那里?

这似乎更有意义:

Complex Complex::operator*( const Complex &operand2 ) const
{
    double Real = (real * operand2.real)-(imaginary * operand2.imaginary);
    double Imaginary = ( real * operand2.imaginary)+(imaginary * operand2.real);

    Complex somenumber ( Real, Imaginary );

    return somenumber;
}
Run Code Online (Sandbox Code Playgroud)

c++ constructor operator-overloading

5
推荐指数
1
解决办法
144
查看次数

在左侧使用auto调用构造函数

#include <iostream>
using namespace std;
struct A {
    A() { cout << "default" << endl; }
    A(const A&) { cout << "copy" << endl; }
    A(A&&) { cout << "move" << endl; }

};
int main() {
    A a{};
    auto aa = A{};
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

该程序将打印default,default在MSVC2013.标准是否表示​​在左侧创建带有auto的对象,或者第二个版本,auto aa = A{};首先调用默认构造函数然后将tmp变量移动/复制到左侧?

c++ constructor auto c++11

5
推荐指数
0
解决办法
41
查看次数

返回局部变量而不复制它们

我是 C++ 的新手,想知道是否有办法在函数中创建对象,然后返回该对象而不必将其复制到内存中。我知道原始本地对象超出范围,但我希望编译器可以优化它,使对象的副本只重用相同的内存地址。

int foo()
{
    int bar = 5;
    std::cout << &bar << std::endl;

    return bar;
}

int main()
{
    char a;
    auto b = foo();
    std::cout << &b << std::endl;
    std::cin >> a;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

这将返回不同的内存地址。既然bar的地址不再需要,而且b的大小总是一样的,那么有什么理由不能只使用相同的地址并省去复制的步骤呢?


对于一个简单的整数并不重要,但对于更大的对象,确保返回的对象不会被复制到内存中的首选方法是什么?

以下是一个好方法吗?

int & foo(int & bar)
{
    std::cout << &bar << std::endl;
    // do things with bar
    return bar;
}

int main()
{
    char a;
    auto bar = 5;
    auto & b = foo(bar);
    std::cout << &b << std::endl;
    std::cin …
Run Code Online (Sandbox Code Playgroud)

c++

5
推荐指数
1
解决办法
1156
查看次数

rvalue作为构造对象的初始化器

我是编程新手.对不起,我的英语不好.我试图使用rvalue作为初始对象的初始化器.因此,根据代码,它将打印出使用的构造函数和赋值运算符.但结果是对象"what2"和"what3",那些不打印任何东西.这是代码:

#include <iostream>
using namespace std;
class X{
public:
    int x;
    X()= default;
    X(int num):x{num}{}
    X(const X& y){
        x = y.x;
        std::cout << "copy constructor" << std::endl;
        std::cout << x << std::endl;

    }
    X& operator=(const X& d){
        x = d.x;
        std::cout << "copy assignment" << std::endl;
        return *this;
    }
    X(X&& y){
        x = y.x;
        std::cout << "move constructor" << std::endl;
    }
    X& operator=(X&& b){
        x = b.x;
        std::cout << "move assignment" << std::endl;
        return *this;
    }
};

X operator +(const …
Run Code Online (Sandbox Code Playgroud)

c++

5
推荐指数
1
解决办法
172
查看次数

关于向量记忆行为的问题

我最近对内存(de)分配感到困惑 std::vectors

让我们假设我得到了整数的正常向量: std::vector<int> intv;当我push_back有时int它会随着时间而增长.当我离开函数的范围(即)时,它会被释放,而不需要额外的调用.

大.让我们举另一个例子:

struct foo_t{
    std::string bar:
    unsigned int derp;
}
void hurr(){
    std::vector<foo_t> foov;
    foo_t foo;
    foo.bar = "Sup?";
    foo.derp = 1337;
    foov.push_back(foo);
}
Run Code Online (Sandbox Code Playgroud)

好的.当我调用hurr()vector创建时,会创建一个foo_t实例,实例将被填充并推送到向量.因此,当我离开函数时,向量将被释放,内容(此处为一个foo_t)也会被释放?

下一个例子:

struct foo_t{
    std::string bar:
    unsigned int derp;
}
std::vector<foo_t> hurr(){
    std::vector<foo_t> foov;
    foo_t foo;
    foo.bar = "Sup?";
    foo.derp = 1337;
    foov.push_back(foo);
    return foov;
}
Run Code Online (Sandbox Code Playgroud)

在我的理解中,向量及其内容存在于堆栈中,它最终被时间覆盖并且我返回的向量和其内容将是无用的.或者它实际上是否返回了带有其内容副本的向量副本(如果它不是POD,则需要内容数据类型的Copy-Constructor)?

显而易见的事情:

struct foo_t{
    std::string bar:
    unsigned int derp;
}
std::vector<foo_t*> hurr(){
    std::vector<foo_t*> foov;
    foo_t …
Run Code Online (Sandbox Code Playgroud)

c++ stl stdvector c++11

5
推荐指数
1
解决办法
236
查看次数

如果没有定义析构函数,为什么返回值优化不会发生?

我希望从这个测试程序中看到命名返回值优化 (NRVO) 的复制省略,但它的输出是“地址不匹配!” 所以 NRVO 没有发生。为什么是这样?

// test.cpp
// Compile using:
//      g++ -Wall -std=c++17 -o test test.cpp
#include <string>
#include <iostream>

void *addr = NULL;

class A
{
public:
    int i;
    int j;

#if 0
    ~A() {}
#endif
};

A fn()
{
    A fn_a;

    addr = &fn_a;

    return fn_a;
}

int main()
{
    A a = fn();

    if (addr == &a)
        std::cout << "Addresses match!\n";
    else
        std::cout << "Addresses do not match!\n";
}
Run Code Online (Sandbox Code Playgroud)

笔记:

  1. 如果通过启用#if上述定义析构函数,则 …

c++ class copy-elision rvo nrvo

5
推荐指数
1
解决办法
223
查看次数

标签 统计

c++ ×10

constructor ×3

c++11 ×2

stl ×2

auto ×1

bstr ×1

class ×1

com ×1

copy ×1

copy-elision ×1

nrvo ×1

operator-overloading ×1

rvo ×1

stdvector ×1