C++ 易踩坑总结以及小技巧

1. for循环中在栈上创建的对象可能具有相同的地址,进行指针操作时需注意;所以循环中最好使用new来创建指针并操作地址;

for (int x : arr) {
	ClassName obj(); \\ it is like to have the same address in every loop
	ClassName obj2 = new ClassName();
	std::cout<<&obj<<std::endl;
}

2. 模板函数的声明与定义最好放到同一个头文件中,否则会出现编译时没有正确找到symbol的错误。

image

3. 对于&等运算符的类外重写最好添加inline,否则可能会出现duplicate symbol的编译错误;

3. 指向子类对象的父类指针无法直接访问子类新添加的成员,但是可以在原本就有的函数中重写此函数来达到间接访问;

#include <iostream>

class Base {
public:
    virtual void func() {
        std::cout << "Base function" << std::endl;
    }
};

class Derived : public Base {
public:
    void func() override {
        std::cout << "Derived function" << std::endl;
        newMember(); // 在重写函数中访问子类的新成员
    }

    void newMember() {
        std::cout << "New member function of Derived" << std::endl;
    }
};

int main() {
    Base* basePtr = new Derived();
    basePtr->func(); // 输出 "Derived function" 和 "New member function of Derived"
    delete basePtr; // 清理内存
    return 0;
}

5 enable_if/enable_if_t

https://www.luozhiyun.com/archives/744

6.为模板参数提供多种构造函数返回方案,编译报错

image
因为在这里,我为模板参数EDGEIT根据成员变量的不同设置了多个构造方法,以期望我对于模板参数EDGEIT的不同实际类针对返回,比如对于类1,定义为有四个参数的构造函数,对于类2定义为有五个参数的构造函数,期望他们就会对应进行选择。
然而在编译过程中,对于每个构建的类都会尝试每个分支的可能性,比如对于类1会尝试三四五所有的分支构造,因为这里是模板参数,我们要使得所有传进来的类都能满足这个参数所做出的所有行为。所以这样的方式是错误的。正确的做法应该是根据参数的不同启用不同的模板函数,即使用std::enable_if这样的
SFINAE技术。

posted @ 2024-10-17 14:20  石中火本火  阅读(4)  评论(0编辑  收藏  举报