是否可以强制通过引用或指针 (C++) 传递 class?

Is it possible to force a class to be passed by reference or pointer (C++)?

我不完全确定要搜索什么以查看是否有人问过这个问题,所以希望它不是重复的。

假设我用 C++ 写了一个 class。当 class 传递给函数 not[=26= 时,是否有可能通过构造函数或其他内部机制(对 class)抛出编译器警告] 参考。

这背后的动机只是为了更有力地控制内存分配。有问题的 class 有几个内存指针,它们是在 class 构造期间分配的(以及通过各种 class 成员函数分配的 freed/allocated )。分配很昂贵,我想警告开发人员(好吧,老实说,我想警告自己)多余的数据副本。但是,在其他情况下有复制 class 的有效用例(甚至可能是按值传递的有效用例……尽管我想不出任何不可避免的用例)。

顺便说一句,class 可以 按值传递 - class 副本 可以 工作.但是,我不希望它被调用,除非它 需要 被调用。因此编译器警告而不是错误。

一个人为的例子:

class doNotSilentCopy {
public:

    doNotSilentCopy(size_t size) {
        mysize = size;
        dummy = (int*)malloc(mysize);
    };
    doNotSilentCopy() : doNotSilentCopy(0) {};

    doNotSilentCopy(const doNotSilentCopy& rhs) {
        this->mysize = rhs.mysize;
        this->dummy = (int*)malloc(this->mysize);
    };

    ~doNotSilentCopy(void) {
        if (dummy) {
            free(dummy);
            dummy = nullptr;
            mysize = 0;
        }
    };

    int get(int index) {
        return *(dummy + index);
    };

private:
    size_t mysize;
    int* dummy;
};

int getDataBad(doNotSilentCopy cls, int index) {
    return cls.get(index);
}

int getDataGood(doNotSilentCopy& cls, int index) {
    return cls.get(index);
}

int main() {
    doNotSilentCopy mycls(10);

    int can_I_warn_about_this = getDataBad(mycls, 5);

    int this_is_acceptable = getDataGood(mycls, 5);

    return 0;
}

要出错,您需要删除复制构造和复制分配。您曾说过要保留它们,但不鼓励使用它们。

幸运的是,现代 C++ 对此也有一个答案——deprecated 属性:

[[deprecated("Please avoid copying objects of this class")]]
DoNotSilentCopy(DoNotSilentCopy const &foo);

[[deprecated("Please avoid copying objects of this class")]]
DoNotSilentCopy &operator=(DoNotSilentCopy const &);

但是请注意,这将导致对对象的任何 副本发出警告,而不仅仅是当它作为参数传递时。

Visual Studio 从 VS 2015 开始实施。

参考

https://docs.microsoft.com/en-us/cpp/cpp/attributes?view=msvc-160

当我输入时,“van dench”给出了简短的回答。 Ted Lyngmo 的话也说得通。 如果您想明确的话,这是代码中的答案。

class NonCopyableNonMoveable
{
public:
    NonCopyableNonMoveable() = default;
    NonCopyableNonMoveable(NonCopyableNonMoveable&&) = delete;
    NonCopyableNonMoveable& operator=(const NonCopyableNonMoveable&) = delete;
    ~NonCopyableNonMoveable() = default;

    NonCopyableNonMoveable Clone()
    {
        return NonCopyableNonMoveable(*this);
    }

private:
    NonCopyableNonMoveable(const NonCopyableNonMoveable&) = default;
};

void f(NonCopyableNonMoveable c)
{
}

int main()
{
    NonCopyableNonMoveable l;
    // f(l); // <== wont compile
    auto copy_of_l = l.Clone();

    return 0;
}