是否可以强制通过引用或指针 (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;
}
我不完全确定要搜索什么以查看是否有人问过这个问题,所以希望它不是重复的。
假设我用 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;
}